Edit

kc3-lang/angle/src/libANGLE/renderer/RenderTargetCache.h

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2019-05-20 11:12:53
    Hash : 6722009e
    Message : Vulkan: Handle dirty RTs with state messages. Prior to this CL we were handling dirty state change notifications by flushing the RT Images just prior to use or just after they were changed. This could lead to a few redundant checks in several places. It also meant we needed an owner pointer from the RT to the parent Image. This pointer would be null for Surfaces and Renderbuffers. This cleans up the image flushing logic to be handled by dirty bit notifications. When an app updates an attached Texture with TexSubImage or related calls it will send a notification to the Framebuffer. The Framebuffer then sets a dirty contents bit that is handled in the implementation. In Vulkan this means flushing the dirty bits. Requires adding a flag to the FramebufferImpl class to determine if we need to syncState before we checkStatus. Adding the option allows us to only call syncState for the GL back-end. Not calling syncState allows the robust resource init operation to happen *before* we syncState. Which in turn allows FramebuffeVk to initialize the VkImages in one go. Added new regression tests for Texture updates. This might not cover all cases. I found it was very hard to trigger some of the resource update staging in TextureVk. Bug: angleproject:3427 Change-Id: Idfa177436ba7fcb9d398f2b67922e085f778f82a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1601552 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>

  • src/libANGLE/renderer/RenderTargetCache.h
  • //
    // 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 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 *getColorRead(const gl::FramebufferState &state) const;
    
      private:
        angle::Result updateCachedRenderTarget(const gl::Context *context,
                                               const gl::FramebufferAttachment *attachment,
                                               RenderTargetT **cachedRenderTarget);
    
        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>
    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_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:
                {
                    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>::updateColorRenderTarget(
        const gl::Context *context,
        const gl::FramebufferState &state,
        size_t colorIndex)
    {
        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, &newRenderTarget));
        }
        *cachedRenderTarget = newRenderTarget;
        return angle::Result::Continue;
    }
    
    template <typename RenderTargetT>
    RenderTargetT *RenderTargetCache<RenderTargetT>::getColorRead(
        const gl::FramebufferState &state) const
    {
        ASSERT(mColorRenderTargets[state.getReadIndex()] &&
               state.getReadIndex() < mColorRenderTargets.size());
        return mColorRenderTargets[state.getReadIndex()];
    }
    
    }  // namespace rx
    
    #endif  // LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_