Edit

kc3-lang/angle/src/libANGLE/renderer/vulkan/ResourceVk.cpp

Branch :

  • Show log

    Commit

  • Author : Tim Van Patten
    Date : 2021-09-07 17:41:11
    Hash : 57d59e83
    Message : Vulkan: Add ResourceWrite to track Read and Write Access vk::Resource currently only tracks accesses in general, not which type of access is being performed. This CL adds the new class ResourceWrite to track whether the access is a Read or Read/Write access and when the access completes. This allows a follow-on CL to know when a buffer is being written to by the GPU or if the GPU is only reading from a buffer. Tracking write accesses to buffers is required when attempting to "Ghost" (duplicate) GPU-read-only buffers to prevent breaking the render pass when the CPU maps the buffer memory. Bug: angleproject:5971 Test: ComputeShaderTest.ImageBufferMapWrite Change-Id: I965e3e75730719ccce77334744ae4feae33c6101 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3146319 Commit-Queue: Tim Van Patten <timvp@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Charlie Lao <cclao@google.com>

  • src/libANGLE/renderer/vulkan/ResourceVk.cpp
  • //
    // Copyright 2017 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.
    //
    // Resource:
    //    Resource lifetime tracking in the Vulkan back-end.
    //
    
    #include "libANGLE/renderer/vulkan/ResourceVk.h"
    
    #include "libANGLE/renderer/vulkan/ContextVk.h"
    
    namespace rx
    {
    namespace vk
    {
    namespace
    {
    angle::Result FinishRunningCommands(ContextVk *contextVk, Serial serial)
    {
        return contextVk->finishToSerial(serial);
    }
    
    template <typename T>
    angle::Result WaitForIdle(ContextVk *contextVk, const char *debugMessage, T *resource)
    {
        // If there are pending commands for the resource, flush them.
        if (resource->usedInRecordedCommands())
        {
            ANGLE_TRY(contextVk->flushImpl(nullptr));
        }
    
        // Make sure the driver is done with the resource.
        if (resource->usedInRunningCommands(contextVk->getLastCompletedQueueSerial()))
        {
            if (debugMessage)
            {
                ANGLE_PERF_WARNING(contextVk->getDebug(), GL_DEBUG_SEVERITY_HIGH, debugMessage);
            }
            ANGLE_TRY(resource->finishRunningCommands(contextVk));
        }
    
        ASSERT(!resource->isCurrentlyInUse(contextVk->getLastCompletedQueueSerial()));
    
        return angle::Result::Continue;
    }
    }  // namespace
    
    // Resource implementation.
    Resource::Resource()
    {
        mUse.init();
    }
    
    Resource::Resource(Resource &&other) : Resource()
    {
        mUse = std::move(other.mUse);
    }
    
    Resource::~Resource()
    {
        mUse.release();
    }
    
    angle::Result Resource::finishRunningCommands(ContextVk *contextVk)
    {
        return FinishRunningCommands(contextVk, mUse.getSerial());
    }
    
    angle::Result Resource::waitForIdle(ContextVk *contextVk, const char *debugMessage)
    {
        return WaitForIdle(contextVk, debugMessage, this);
    }
    
    // Resource implementation.
    ReadWriteResource::ReadWriteResource()
    {
        mReadOnlyUse.init();
        mReadWriteUse.init();
    }
    
    ReadWriteResource::ReadWriteResource(ReadWriteResource &&other) : ReadWriteResource()
    {
        mReadOnlyUse  = std::move(other.mReadOnlyUse);
        mReadWriteUse = std::move(other.mReadWriteUse);
    }
    
    ReadWriteResource::~ReadWriteResource()
    {
        mReadOnlyUse.release();
        mReadWriteUse.release();
    }
    
    angle::Result ReadWriteResource::finishRunningCommands(ContextVk *contextVk)
    {
        return FinishRunningCommands(contextVk, mReadOnlyUse.getSerial());
    }
    
    angle::Result ReadWriteResource::waitForIdle(ContextVk *contextVk, const char *debugMessage)
    {
        return WaitForIdle(contextVk, debugMessage, this);
    }
    
    // SharedGarbage implementation.
    SharedGarbage::SharedGarbage() = default;
    
    SharedGarbage::SharedGarbage(SharedGarbage &&other)
    {
        *this = std::move(other);
    }
    
    SharedGarbage::SharedGarbage(SharedResourceUse &&use, std::vector<GarbageObject> &&garbage)
        : mLifetime(std::move(use)), mGarbage(std::move(garbage))
    {}
    
    SharedGarbage::~SharedGarbage() = default;
    
    SharedGarbage &SharedGarbage::operator=(SharedGarbage &&rhs)
    {
        std::swap(mLifetime, rhs.mLifetime);
        std::swap(mGarbage, rhs.mGarbage);
        return *this;
    }
    
    bool SharedGarbage::destroyIfComplete(RendererVk *renderer, Serial completedSerial)
    {
        if (mLifetime.isCurrentlyInUse(completedSerial))
            return false;
    
        for (GarbageObject &object : mGarbage)
        {
            object.destroy(renderer);
        }
    
        mLifetime.release();
    
        return true;
    }
    
    // ResourceUseList implementation.
    ResourceUseList::ResourceUseList()
    {
        constexpr size_t kDefaultResourceUseCount = 4096;
        mResourceUses.reserve(kDefaultResourceUseCount);
    }
    
    ResourceUseList::ResourceUseList(ResourceUseList &&other)
    {
        *this = std::move(other);
    }
    
    ResourceUseList::~ResourceUseList()
    {
        ASSERT(mResourceUses.empty());
    }
    
    ResourceUseList &ResourceUseList::operator=(ResourceUseList &&rhs)
    {
        std::swap(mResourceUses, rhs.mResourceUses);
        return *this;
    }
    
    void ResourceUseList::releaseResourceUses()
    {
        for (SharedResourceUse &use : mResourceUses)
        {
            use.release();
        }
    
        mResourceUses.clear();
    }
    
    void ResourceUseList::releaseResourceUsesAndUpdateSerials(Serial serial)
    {
        for (SharedResourceUse &use : mResourceUses)
        {
            use.releaseAndUpdateSerial(serial);
        }
    
        mResourceUses.clear();
    }
    }  // namespace vk
    }  // namespace rx