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, ...@@ -53,33 +53,12 @@ gl::Error MarkAttachmentsDirty(const gl::Context *context,
return gl::NoError(); 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 } // anonymous namespace
Framebuffer11::Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer) Framebuffer11::Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer)
: FramebufferD3D(data, renderer), mRenderer(renderer), mCachedDepthStencilRenderTarget(nullptr) : FramebufferD3D(data, renderer), mRenderer(renderer)
{ {
ASSERT(mRenderer != nullptr); ASSERT(mRenderer != nullptr);
mCachedColorRenderTargets.fill(nullptr);
} }
Framebuffer11::~Framebuffer11() Framebuffer11::~Framebuffer11()
...@@ -378,48 +357,10 @@ GLenum Framebuffer11::getRenderTargetImplementationFormat(RenderTargetD3D *rende ...@@ -378,48 +357,10 @@ GLenum Framebuffer11::getRenderTargetImplementationFormat(RenderTargetD3D *rende
return renderTarget11->getFormatSet().format().fboImplementationInternalFormat; 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, void Framebuffer11::syncState(const gl::Context *context,
const gl::Framebuffer::DirtyBits &dirtyBits) const gl::Framebuffer::DirtyBits &dirtyBits)
{ {
for (auto dirtyBit : dirtyBits) mRenderTargetCache.update(context, mState, 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;
}
}
}
FramebufferD3D::syncState(context, dirtyBits); FramebufferD3D::syncState(context, dirtyBits);
...@@ -445,7 +386,7 @@ gl::Error Framebuffer11::getSamplePosition(size_t index, GLfloat *xy) const ...@@ -445,7 +386,7 @@ gl::Error Framebuffer11::getSamplePosition(size_t index, GLfloat *xy) const
RenderTarget11 *Framebuffer11::getFirstRenderTarget() const RenderTarget11 *Framebuffer11::getFirstRenderTarget() const
{ {
for (auto *renderTarget : mCachedColorRenderTargets) for (auto *renderTarget : mRenderTargetCache.getColors())
{ {
if (renderTarget) if (renderTarget)
{ {
...@@ -453,7 +394,7 @@ RenderTarget11 *Framebuffer11::getFirstRenderTarget() const ...@@ -453,7 +394,7 @@ RenderTarget11 *Framebuffer11::getFirstRenderTarget() const
} }
} }
return mCachedDepthStencilRenderTarget; return mRenderTargetCache.getDepthStencil();
} }
} // namespace rx } // namespace rx
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_
#include "libANGLE/Observer.h" #include "libANGLE/Observer.h"
#include "libANGLE/renderer/RenderTargetCache.h"
#include "libANGLE/renderer/d3d/FramebufferD3D.h" #include "libANGLE/renderer/d3d/FramebufferD3D.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
...@@ -38,13 +39,13 @@ class Framebuffer11 : public FramebufferD3D ...@@ -38,13 +39,13 @@ class Framebuffer11 : public FramebufferD3D
void syncState(const gl::Context *context, void syncState(const gl::Context *context,
const gl::Framebuffer::DirtyBits &dirtyBits) override; 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 const RenderTarget11 *getCachedDepthStencilRenderTarget() const
{ {
return mCachedDepthStencilRenderTarget; return mRenderTargetCache.getDepthStencil();
} }
RenderTarget11 *getFirstRenderTarget() const; RenderTarget11 *getFirstRenderTarget() const;
...@@ -81,12 +82,8 @@ class Framebuffer11 : public FramebufferD3D ...@@ -81,12 +82,8 @@ class Framebuffer11 : public FramebufferD3D
GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override; GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override;
void updateColorRenderTarget(const gl::Context *context, size_t colorIndex);
void updateDepthStencilRenderTarget(const gl::Context *context);
Renderer11 *const mRenderer; Renderer11 *const mRenderer;
RenderTargetArray11 mCachedColorRenderTargets; RenderTargetCache<RenderTarget11> mRenderTargetCache;
RenderTarget11 *mCachedDepthStencilRenderTarget;
}; };
} // namespace rx } // namespace rx
......
...@@ -33,7 +33,6 @@ class Renderer11; ...@@ -33,7 +33,6 @@ class Renderer11;
class RenderTarget11; class RenderTarget11;
struct Renderer11DeviceCaps; struct Renderer11DeviceCaps;
using RenderTargetArray11 = std::array<RenderTarget11 *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
using RTVArray = std::array<ID3D11RenderTargetView *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>; using RTVArray = std::array<ID3D11RenderTargetView *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
namespace gl_d3d11 namespace gl_d3d11
......
...@@ -24,33 +24,10 @@ ...@@ -24,33 +24,10 @@
namespace rx 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) Framebuffer9::Framebuffer9(const gl::FramebufferState &data, Renderer9 *renderer)
: FramebufferD3D(data, renderer), mRenderer(renderer), mCachedDepthStencilRenderTarget(nullptr) : FramebufferD3D(data, renderer), mRenderer(renderer)
{ {
ASSERT(mRenderer != nullptr); ASSERT(mRenderer != nullptr);
mCachedColorRenderTargets.fill(nullptr);
} }
Framebuffer9::~Framebuffer9() Framebuffer9::~Framebuffer9()
...@@ -83,8 +60,8 @@ gl::Error Framebuffer9::invalidateSub(const gl::Context *context, ...@@ -83,8 +60,8 @@ gl::Error Framebuffer9::invalidateSub(const gl::Context *context,
gl::Error Framebuffer9::clearImpl(const gl::Context *context, const ClearParameters &clearParams) gl::Error Framebuffer9::clearImpl(const gl::Context *context, const ClearParameters &clearParams)
{ {
ANGLE_TRY(mRenderer->applyRenderTarget(context, mCachedColorRenderTargets[0], ANGLE_TRY(mRenderer->applyRenderTarget(context, mRenderTargetCache.getColors()[0],
mCachedDepthStencilRenderTarget)); mRenderTargetCache.getDepthStencil()));
const gl::State &glState = context->getGLState(); const gl::State &glState = context->getGLState();
float nearZ = glState.getNearPlane(); float nearZ = glState.getNearPlane();
...@@ -94,8 +71,8 @@ gl::Error Framebuffer9::clearImpl(const gl::Context *context, const ClearParamet ...@@ -94,8 +71,8 @@ gl::Error Framebuffer9::clearImpl(const gl::Context *context, const ClearParamet
mRenderer->setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled()); mRenderer->setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
return mRenderer->clear(context, clearParams, mCachedColorRenderTargets[0], return mRenderer->clear(context, clearParams, mRenderTargetCache.getColors()[0],
mCachedDepthStencilRenderTarget); mRenderTargetCache.getDepthStencil());
} }
gl::Error Framebuffer9::readPixelsImpl(const gl::Context *context, gl::Error Framebuffer9::readPixelsImpl(const gl::Context *context,
...@@ -435,46 +412,6 @@ void Framebuffer9::syncState(const gl::Context *context, ...@@ -435,46 +412,6 @@ void Framebuffer9::syncState(const gl::Context *context,
const gl::Framebuffer::DirtyBits &dirtyBits) const gl::Framebuffer::DirtyBits &dirtyBits)
{ {
FramebufferD3D::syncState(context, dirtyBits); FramebufferD3D::syncState(context, dirtyBits);
mRenderTargetCache.update(context, mState, 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);
} }
} // namespace rx } // namespace rx
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#ifndef LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_ #ifndef LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_
#define 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/FramebufferD3D.h"
#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" #include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
...@@ -36,14 +37,14 @@ class Framebuffer9 : public FramebufferD3D ...@@ -36,14 +37,14 @@ class Framebuffer9 : public FramebufferD3D
void syncState(const gl::Context *context, void syncState(const gl::Context *context,
const gl::Framebuffer::DirtyBits &dirtyBits) override; 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 const RenderTarget9 *getCachedDepthStencilRenderTarget() const
{ {
return mCachedDepthStencilRenderTarget; return mRenderTargetCache.getDepthStencil();
} }
private: private:
...@@ -69,13 +70,9 @@ class Framebuffer9 : public FramebufferD3D ...@@ -69,13 +70,9 @@ class Framebuffer9 : public FramebufferD3D
GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override; GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override;
void updateColorRenderTarget(const gl::Context *context, size_t colorIndex);
void updateDepthStencilRenderTarget(const gl::Context *context);
Renderer9 *const mRenderer; Renderer9 *const mRenderer;
RenderTargetArray9 mCachedColorRenderTargets; RenderTargetCache<RenderTarget9> mRenderTargetCache;
RenderTarget9 *mCachedDepthStencilRenderTarget;
}; };
} // namespace rx } // namespace rx
......
...@@ -24,8 +24,6 @@ namespace rx ...@@ -24,8 +24,6 @@ namespace rx
{ {
class RenderTarget9; class RenderTarget9;
using RenderTargetArray9 = std::array<RenderTarget9 *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
namespace gl_d3d9 namespace gl_d3d9
{ {
......
...@@ -273,6 +273,7 @@ ...@@ -273,6 +273,7 @@
'libANGLE/renderer/ProgramPipelineImpl.h', 'libANGLE/renderer/ProgramPipelineImpl.h',
'libANGLE/renderer/QueryImpl.h', 'libANGLE/renderer/QueryImpl.h',
'libANGLE/renderer/RenderbufferImpl.h', 'libANGLE/renderer/RenderbufferImpl.h',
'libANGLE/renderer/RenderTargetCache.h',
'libANGLE/renderer/SamplerImpl.h', 'libANGLE/renderer/SamplerImpl.h',
'libANGLE/renderer/ShaderImpl.h', 'libANGLE/renderer/ShaderImpl.h',
'libANGLE/renderer/StreamProducerImpl.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