Commit 443c57f6 by Jamie Madill Committed by Commit Bot

Add RenderTargetCache helper.

This class encapsulates the Framebuffer::syncState update pattern that caches the RenderTargets for the back-end. RenderTargets abstract away the differences between Textures/Renderbuffers/Surfaces for the back-end and allows the back-end to treat the various types the same. This helper class allows sharing code to cache the RenderTargets. Bug:angleproject:2372 Change-Id: Ib2beb28a616dee1d34c485cd1a19b7202ef70a60 Reviewed-on: https://chromium-review.googlesource.com/948783Reviewed-by: 's avatarLuc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent e3688d27
//
// 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();
void update(const gl::Context *context,
const gl::FramebufferState &state,
const gl::Framebuffer::DirtyBits &dirtyBits);
using RenderTargetArray = gl::AttachmentArray<RenderTargetT *>;
const RenderTargetArray &getColors() const;
RenderTargetT *getDepthStencil() const;
private:
void updateCachedRenderTarget(const gl::Context *context,
const gl::FramebufferAttachment *attachment,
RenderTargetT **cachedRenderTarget);
void updateColorRenderTarget(const gl::Context *context,
const gl::FramebufferState &state,
size_t colorIndex);
void updateDepthStencilRenderTarget(const gl::Context *context,
const gl::FramebufferState &state);
gl::AttachmentArray<RenderTargetT *> mColorRenderTargets;
// We only support a single Depth/Stencil RenderTarget currently.
RenderTargetT *mDepthStencilRenderTarget;
};
template <typename RenderTargetT>
RenderTargetCache<RenderTargetT>::RenderTargetCache()
: mColorRenderTargets{{nullptr}}, mDepthStencilRenderTarget(nullptr)
{
}
template <typename RenderTargetT>
RenderTargetCache<RenderTargetT>::~RenderTargetCache()
{
}
template <typename RenderTargetT>
void 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:
updateDepthStencilRenderTarget(context, state);
break;
case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS:
case gl::Framebuffer::DIRTY_BIT_READ_BUFFER:
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:
{
ASSERT(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 &&
dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX);
size_t colorIndex =
static_cast<size_t>(dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0);
updateColorRenderTarget(context, state, colorIndex);
break;
}
}
}
}
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>
void RenderTargetCache<RenderTargetT>::updateColorRenderTarget(const gl::Context *context,
const gl::FramebufferState &state,
size_t colorIndex)
{
updateCachedRenderTarget(context, state.getColorAttachment(colorIndex),
&mColorRenderTargets[colorIndex]);
}
template <typename RenderTargetT>
void RenderTargetCache<RenderTargetT>::updateDepthStencilRenderTarget(
const gl::Context *context,
const gl::FramebufferState &state)
{
updateCachedRenderTarget(context, state.getDepthOrStencilAttachment(),
&mDepthStencilRenderTarget);
}
template <typename RenderTargetT>
void RenderTargetCache<RenderTargetT>::updateCachedRenderTarget(
const gl::Context *context,
const gl::FramebufferAttachment *attachment,
RenderTargetT **cachedRenderTarget)
{
RenderTargetT *newRenderTarget = nullptr;
if (attachment)
{
ASSERT(attachment->isAttached());
// TODO(jmadill): Don't swallow this error.
ANGLE_SWALLOW_ERR(attachment->getRenderTarget(context, &newRenderTarget));
}
*cachedRenderTarget = newRenderTarget;
}
} // namespace rx
#endif // LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_
......@@ -53,33 +53,12 @@ gl::Error MarkAttachmentsDirty(const gl::Context *context,
return gl::NoError();
}
void UpdateCachedRenderTarget(const gl::Context *context,
const gl::FramebufferAttachment *attachment,
RenderTarget11 *&cachedRenderTarget)
{
RenderTarget11 *newRenderTarget = nullptr;
if (attachment)
{
// TODO(jmadill): Don't swallow this error.
gl::Error error = attachment->getRenderTarget(context, &newRenderTarget);
if (error.isError())
{
ERR() << "Internal rendertarget error: " << error;
}
}
if (newRenderTarget != cachedRenderTarget)
{
cachedRenderTarget = newRenderTarget;
}
}
} // anonymous namespace
Framebuffer11::Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer)
: FramebufferD3D(data, renderer), mRenderer(renderer), mCachedDepthStencilRenderTarget(nullptr)
: FramebufferD3D(data, renderer), mRenderer(renderer)
{
ASSERT(mRenderer != nullptr);
mCachedColorRenderTargets.fill(nullptr);
}
Framebuffer11::~Framebuffer11()
......@@ -378,48 +357,10 @@ GLenum Framebuffer11::getRenderTargetImplementationFormat(RenderTargetD3D *rende
return renderTarget11->getFormatSet().format().fboImplementationInternalFormat;
}
void Framebuffer11::updateColorRenderTarget(const gl::Context *context, size_t colorIndex)
{
UpdateCachedRenderTarget(context, mState.getColorAttachment(colorIndex),
mCachedColorRenderTargets[colorIndex]);
}
void Framebuffer11::updateDepthStencilRenderTarget(const gl::Context *context)
{
UpdateCachedRenderTarget(context, mState.getDepthOrStencilAttachment(),
mCachedDepthStencilRenderTarget);
}
void Framebuffer11::syncState(const gl::Context *context,
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:
updateDepthStencilRenderTarget(context);
break;
case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS:
case gl::Framebuffer::DIRTY_BIT_READ_BUFFER:
break;
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:
{
ASSERT(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 &&
dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX);
size_t colorIndex =
static_cast<size_t>(dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0);
updateColorRenderTarget(context, colorIndex);
break;
}
}
}
mRenderTargetCache.update(context, mState, dirtyBits);
FramebufferD3D::syncState(context, dirtyBits);
......@@ -445,7 +386,7 @@ gl::Error Framebuffer11::getSamplePosition(size_t index, GLfloat *xy) const
RenderTarget11 *Framebuffer11::getFirstRenderTarget() const
{
for (auto *renderTarget : mCachedColorRenderTargets)
for (auto *renderTarget : mRenderTargetCache.getColors())
{
if (renderTarget)
{
......@@ -453,7 +394,7 @@ RenderTarget11 *Framebuffer11::getFirstRenderTarget() const
}
}
return mCachedDepthStencilRenderTarget;
return mRenderTargetCache.getDepthStencil();
}
} // namespace rx
......@@ -10,6 +10,7 @@
#define LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_
#include "libANGLE/Observer.h"
#include "libANGLE/renderer/RenderTargetCache.h"
#include "libANGLE/renderer/d3d/FramebufferD3D.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
......@@ -38,13 +39,13 @@ class Framebuffer11 : public FramebufferD3D
void syncState(const gl::Context *context,
const gl::Framebuffer::DirtyBits &dirtyBits) override;
const RenderTargetArray11 &getCachedColorRenderTargets() const
const gl::AttachmentArray<RenderTarget11 *> &getCachedColorRenderTargets() const
{
return mCachedColorRenderTargets;
return mRenderTargetCache.getColors();
}
const RenderTarget11 *getCachedDepthStencilRenderTarget() const
{
return mCachedDepthStencilRenderTarget;
return mRenderTargetCache.getDepthStencil();
}
RenderTarget11 *getFirstRenderTarget() const;
......@@ -81,12 +82,8 @@ class Framebuffer11 : public FramebufferD3D
GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override;
void updateColorRenderTarget(const gl::Context *context, size_t colorIndex);
void updateDepthStencilRenderTarget(const gl::Context *context);
Renderer11 *const mRenderer;
RenderTargetArray11 mCachedColorRenderTargets;
RenderTarget11 *mCachedDepthStencilRenderTarget;
RenderTargetCache<RenderTarget11> mRenderTargetCache;
};
} // namespace rx
......
......@@ -33,7 +33,6 @@ class Renderer11;
class RenderTarget11;
struct Renderer11DeviceCaps;
using RenderTargetArray11 = std::array<RenderTarget11 *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
using RTVArray = std::array<ID3D11RenderTargetView *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
namespace gl_d3d11
......
......@@ -24,33 +24,10 @@
namespace rx
{
namespace
{
void UpdateCachedRenderTarget(const gl::Context *context,
const gl::FramebufferAttachment *attachment,
RenderTarget9 *&cachedRenderTarget)
{
RenderTarget9 *newRenderTarget = nullptr;
if (attachment)
{
// TODO(jmadill): Don't swallow this error.
gl::Error error = attachment->getRenderTarget(context, &newRenderTarget);
if (error.isError())
{
ERR() << "Internal rendertarget error: " << error;
}
}
if (newRenderTarget != cachedRenderTarget)
{
cachedRenderTarget = newRenderTarget;
}
}
} // anonymous namespace
Framebuffer9::Framebuffer9(const gl::FramebufferState &data, Renderer9 *renderer)
: FramebufferD3D(data, renderer), mRenderer(renderer), mCachedDepthStencilRenderTarget(nullptr)
: FramebufferD3D(data, renderer), mRenderer(renderer)
{
ASSERT(mRenderer != nullptr);
mCachedColorRenderTargets.fill(nullptr);
}
Framebuffer9::~Framebuffer9()
......@@ -83,8 +60,8 @@ gl::Error Framebuffer9::invalidateSub(const gl::Context *context,
gl::Error Framebuffer9::clearImpl(const gl::Context *context, const ClearParameters &clearParams)
{
ANGLE_TRY(mRenderer->applyRenderTarget(context, mCachedColorRenderTargets[0],
mCachedDepthStencilRenderTarget));
ANGLE_TRY(mRenderer->applyRenderTarget(context, mRenderTargetCache.getColors()[0],
mRenderTargetCache.getDepthStencil()));
const gl::State &glState = context->getGLState();
float nearZ = glState.getNearPlane();
......@@ -94,8 +71,8 @@ gl::Error Framebuffer9::clearImpl(const gl::Context *context, const ClearParamet
mRenderer->setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
return mRenderer->clear(context, clearParams, mCachedColorRenderTargets[0],
mCachedDepthStencilRenderTarget);
return mRenderer->clear(context, clearParams, mRenderTargetCache.getColors()[0],
mRenderTargetCache.getDepthStencil());
}
gl::Error Framebuffer9::readPixelsImpl(const gl::Context *context,
......@@ -435,46 +412,6 @@ void Framebuffer9::syncState(const gl::Context *context,
const gl::Framebuffer::DirtyBits &dirtyBits)
{
FramebufferD3D::syncState(context, dirtyBits);
for (auto dirtyBit : dirtyBits)
{
switch (dirtyBit)
{
case gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT:
case gl::Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT:
updateDepthStencilRenderTarget(context);
break;
case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS:
case gl::Framebuffer::DIRTY_BIT_READ_BUFFER:
break;
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:
{
ASSERT(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 &&
dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX);
size_t colorIndex =
static_cast<size_t>(dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0);
updateColorRenderTarget(context, colorIndex);
break;
}
}
}
}
void Framebuffer9::updateColorRenderTarget(const gl::Context *context, size_t colorIndex)
{
UpdateCachedRenderTarget(context, mState.getColorAttachment(colorIndex),
mCachedColorRenderTargets[colorIndex]);
}
void Framebuffer9::updateDepthStencilRenderTarget(const gl::Context *context)
{
UpdateCachedRenderTarget(context, mState.getDepthOrStencilAttachment(),
mCachedDepthStencilRenderTarget);
mRenderTargetCache.update(context, mState, dirtyBits);
}
} // namespace rx
......@@ -9,6 +9,7 @@
#ifndef LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_
#define LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_
#include "libANGLE/renderer/RenderTargetCache.h"
#include "libANGLE/renderer/d3d/FramebufferD3D.h"
#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
......@@ -36,14 +37,14 @@ class Framebuffer9 : public FramebufferD3D
void syncState(const gl::Context *context,
const gl::Framebuffer::DirtyBits &dirtyBits) override;
const RenderTargetArray9 &getCachedColorRenderTargets() const
const gl::AttachmentArray<RenderTarget9 *> &getCachedColorRenderTargets() const
{
return mCachedColorRenderTargets;
return mRenderTargetCache.getColors();
}
const RenderTarget9 *getCachedDepthStencilRenderTarget() const
{
return mCachedDepthStencilRenderTarget;
return mRenderTargetCache.getDepthStencil();
}
private:
......@@ -69,13 +70,9 @@ class Framebuffer9 : public FramebufferD3D
GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override;
void updateColorRenderTarget(const gl::Context *context, size_t colorIndex);
void updateDepthStencilRenderTarget(const gl::Context *context);
Renderer9 *const mRenderer;
RenderTargetArray9 mCachedColorRenderTargets;
RenderTarget9 *mCachedDepthStencilRenderTarget;
RenderTargetCache<RenderTarget9> mRenderTargetCache;
};
} // namespace rx
......
......@@ -24,8 +24,6 @@ namespace rx
{
class RenderTarget9;
using RenderTargetArray9 = std::array<RenderTarget9 *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
namespace gl_d3d9
{
......
......@@ -273,6 +273,7 @@
'libANGLE/renderer/ProgramPipelineImpl.h',
'libANGLE/renderer/QueryImpl.h',
'libANGLE/renderer/RenderbufferImpl.h',
'libANGLE/renderer/RenderTargetCache.h',
'libANGLE/renderer/SamplerImpl.h',
'libANGLE/renderer/ShaderImpl.h',
'libANGLE/renderer/StreamProducerImpl.h',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment