Vulkan: refactor CommandGraphResource

Merged back RecordableGraphResource into CommandGraphResource.  Queries
didn't really need to be a resource, as they always inserted separate
single-command nodes in the graph.  The CommandGraph class is augmented
with a few functions that generate such nodes.

This is in preparation for debug markers, as they too require such
nodes.

Bug: angleproject:2853
Change-Id: I5251a0e0fdd42ed1126921b4acc13687a14af9cd
Reviewed-on: https://chromium-review.googlesource.com/c/1422549
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/CommandGraph.cpp b/src/libANGLE/renderer/vulkan/CommandGraph.cpp
index 979b1e7..adce3e3 100644
--- a/src/libANGLE/renderer/vulkan/CommandGraph.cpp
+++ b/src/libANGLE/renderer/vulkan/CommandGraph.cpp
@@ -83,7 +83,7 @@
 
 // CommandGraphResource implementation.
 CommandGraphResource::CommandGraphResource(CommandGraphResourceType resourceType)
-    : mResourceType(resourceType), mCurrentWritingNode(nullptr)
+    : mCurrentWritingNode(nullptr), mResourceType(resourceType)
 {}
 
 CommandGraphResource::~CommandGraphResource() = default;
@@ -93,22 +93,8 @@
     return renderer->isSerialInUse(mStoredQueueSerial);
 }
 
-bool CommandGraphResource::hasPendingWork(RendererVk *renderer) const
-{
-    // If the renderer has a queue serial higher than the stored one, the command buffers recorded
-    // by this resource have already been submitted, so there is no pending work.
-    return mStoredQueueSerial == renderer->getCurrentQueueSerial();
-}
-
-// RecordableGraphResource implementation.
-RecordableGraphResource::RecordableGraphResource(CommandGraphResourceType resourceType)
-    : CommandGraphResource(resourceType)
-{}
-
-RecordableGraphResource::~RecordableGraphResource() = default;
-
-angle::Result RecordableGraphResource::recordCommands(Context *context,
-                                                      CommandBuffer **commandBufferOut)
+angle::Result CommandGraphResource::recordCommands(Context *context,
+                                                   CommandBuffer **commandBufferOut)
 {
     updateQueueSerial(context->getRenderer()->getCurrentQueueSerial());
 
@@ -133,18 +119,18 @@
     return angle::Result::Continue;
 }
 
-const gl::Rectangle &RecordableGraphResource::getRenderPassRenderArea() const
+const gl::Rectangle &CommandGraphResource::getRenderPassRenderArea() const
 {
     ASSERT(hasStartedRenderPass());
     return mCurrentWritingNode->getRenderPassRenderArea();
 }
 
-angle::Result RecordableGraphResource::beginRenderPass(ContextVk *contextVk,
-                                                       const Framebuffer &framebuffer,
-                                                       const gl::Rectangle &renderArea,
-                                                       const RenderPassDesc &renderPassDesc,
-                                                       const std::vector<VkClearValue> &clearValues,
-                                                       CommandBuffer **commandBufferOut)
+angle::Result CommandGraphResource::beginRenderPass(ContextVk *contextVk,
+                                                    const Framebuffer &framebuffer,
+                                                    const gl::Rectangle &renderArea,
+                                                    const RenderPassDesc &renderPassDesc,
+                                                    const std::vector<VkClearValue> &clearValues,
+                                                    CommandBuffer **commandBufferOut)
 {
     // If a barrier has been inserted in the meantime, stop the command buffer.
     if (!hasChildlessWritingNode())
@@ -161,7 +147,7 @@
     return mCurrentWritingNode->beginInsideRenderPassRecording(contextVk, commandBufferOut);
 }
 
-void RecordableGraphResource::addWriteDependency(RecordableGraphResource *writingResource)
+void CommandGraphResource::addWriteDependency(CommandGraphResource *writingResource)
 {
     CommandGraphNode *writingNode = writingResource->mCurrentWritingNode;
     ASSERT(writingNode);
@@ -169,7 +155,7 @@
     onWriteImpl(writingNode, writingResource->getStoredQueueSerial());
 }
 
-void RecordableGraphResource::addReadDependency(RecordableGraphResource *readingResource)
+void CommandGraphResource::addReadDependency(CommandGraphResource *readingResource)
 {
     updateQueueSerial(readingResource->getStoredQueueSerial());
 
@@ -186,12 +172,12 @@
     mCurrentReadingNodes.push_back(readingNode);
 }
 
-void RecordableGraphResource::finishCurrentCommands(RendererVk *renderer)
+void CommandGraphResource::finishCurrentCommands(RendererVk *renderer)
 {
     startNewCommands(renderer);
 }
 
-void RecordableGraphResource::startNewCommands(RendererVk *renderer)
+void CommandGraphResource::startNewCommands(RendererVk *renderer)
 {
     CommandGraphNode *newCommands =
         renderer->getCommandGraph()->allocateNode(CommandGraphNodeFunction::Generic);
@@ -199,7 +185,7 @@
     onWriteImpl(newCommands, renderer->getCurrentQueueSerial());
 }
 
-void RecordableGraphResource::onWriteImpl(CommandGraphNode *writingNode, Serial currentSerial)
+void CommandGraphResource::onWriteImpl(CommandGraphNode *writingNode, Serial currentSerial)
 {
     updateQueueSerial(currentSerial);
 
@@ -219,44 +205,6 @@
     mCurrentWritingNode = writingNode;
 }
 
-// QueryGraphResource implementation.
-QueryGraphResource::QueryGraphResource() : CommandGraphResource(CommandGraphResourceType::Query) {}
-
-QueryGraphResource::~QueryGraphResource() = default;
-
-void QueryGraphResource::beginQuery(Context *context,
-                                    const QueryPool *queryPool,
-                                    uint32_t queryIndex)
-{
-    startNewCommands(context->getRenderer(), CommandGraphNodeFunction::BeginQuery);
-    mCurrentWritingNode->setQueryPool(queryPool, queryIndex);
-}
-
-void QueryGraphResource::endQuery(Context *context, const QueryPool *queryPool, uint32_t queryIndex)
-{
-    startNewCommands(context->getRenderer(), CommandGraphNodeFunction::EndQuery);
-    mCurrentWritingNode->setQueryPool(queryPool, queryIndex);
-}
-
-void QueryGraphResource::writeTimestamp(Context *context,
-                                        const QueryPool *queryPool,
-                                        uint32_t queryIndex)
-{
-    startNewCommands(context->getRenderer(), CommandGraphNodeFunction::WriteTimestamp);
-    mCurrentWritingNode->setQueryPool(queryPool, queryIndex);
-}
-
-void QueryGraphResource::startNewCommands(RendererVk *renderer, CommandGraphNodeFunction function)
-{
-    CommandGraph *commandGraph = renderer->getCommandGraph();
-    CommandGraphNode *newNode  = commandGraph->allocateNode(function);
-    newNode->setDiagnosticInfo(mResourceType, reinterpret_cast<uintptr_t>(this));
-    commandGraph->setNewBarrier(newNode);
-
-    mStoredQueueSerial  = renderer->getCurrentQueueSerial();
-    mCurrentWritingNode = newNode;
-}
-
 // CommandGraphNode implementation.
 CommandGraphNode::CommandGraphNode(CommandGraphNodeFunction function)
     : mRenderPassClearValues{},
@@ -556,6 +504,16 @@
     return newCommands;
 }
 
+CommandGraphNode *CommandGraph::allocateBarrierNode(CommandGraphResourceType resourceType,
+                                                    CommandGraphNodeFunction function)
+{
+    CommandGraphNode *newNode = allocateNode(function);
+    newNode->setDiagnosticInfo(resourceType, 0);
+    setNewBarrier(newNode);
+
+    return newNode;
+}
+
 void CommandGraph::setNewBarrier(CommandGraphNode *newBarrier)
 {
     size_t previousBarrierIndex       = 0;
@@ -681,6 +639,27 @@
     mNodes.clear();
 }
 
+void CommandGraph::beginQuery(const QueryPool *queryPool, uint32_t queryIndex)
+{
+    CommandGraphNode *newNode =
+        allocateBarrierNode(CommandGraphResourceType::Query, CommandGraphNodeFunction::BeginQuery);
+    newNode->setQueryPool(queryPool, queryIndex);
+}
+
+void CommandGraph::endQuery(const QueryPool *queryPool, uint32_t queryIndex)
+{
+    CommandGraphNode *newNode =
+        allocateBarrierNode(CommandGraphResourceType::Query, CommandGraphNodeFunction::EndQuery);
+    newNode->setQueryPool(queryPool, queryIndex);
+}
+
+void CommandGraph::writeTimestamp(const QueryPool *queryPool, uint32_t queryIndex)
+{
+    CommandGraphNode *newNode = allocateBarrierNode(CommandGraphResourceType::Query,
+                                                    CommandGraphNodeFunction::WriteTimestamp);
+    newNode->setQueryPool(queryPool, queryIndex);
+}
+
 // Dumps the command graph into a dot file that works with graphviz.
 void CommandGraph::dumpGraphDotFile(std::ostream &out) const
 {
diff --git a/src/libANGLE/renderer/vulkan/CommandGraph.h b/src/libANGLE/renderer/vulkan/CommandGraph.h
index 840f6bd..1314da5 100644
--- a/src/libANGLE/renderer/vulkan/CommandGraph.h
+++ b/src/libANGLE/renderer/vulkan/CommandGraph.h
@@ -206,37 +206,15 @@
     // Returns true if the resource is in use by the renderer.
     bool isResourceInUse(RendererVk *renderer) const;
 
-    // Returns true if the resource has unsubmitted work pending.
-    bool hasPendingWork(RendererVk *renderer) const;
-
     // Get the current queue serial for this resource. Used to release resources, and for
     // queries, to know if the queue they are submitted on has finished execution.
     Serial getStoredQueueSerial() const { return mStoredQueueSerial; }
 
-  protected:
-    explicit CommandGraphResource(CommandGraphResourceType resourceType);
-
-    Serial mStoredQueueSerial;
-
-    // Additional diagnostic information.
-    CommandGraphResourceType mResourceType;
-
-    // Current command graph writing node.
-    CommandGraphNode *mCurrentWritingNode;
-};
-
-// Subclass of graph resources that can record command buffers. Images/Buffers/Framebuffers.
-// Does not include Query graph resources.
-class RecordableGraphResource : public CommandGraphResource
-{
-  public:
-    ~RecordableGraphResource() override;
-
     // Sets up dependency relations. 'this' resource is the resource being written to.
-    void addWriteDependency(RecordableGraphResource *writingResource);
+    void addWriteDependency(CommandGraphResource *writingResource);
 
     // Sets up dependency relations. 'this' resource is the resource being read.
-    void addReadDependency(RecordableGraphResource *readingResource);
+    void addReadDependency(CommandGraphResource *readingResource);
 
     // Updates the in-use serial tracked for this resource. Will clear dependencies if the resource
     // was not used in this set of command nodes.
@@ -297,7 +275,7 @@
     }
 
   protected:
-    explicit RecordableGraphResource(CommandGraphResourceType resourceType);
+    explicit CommandGraphResource(CommandGraphResourceType resourceType);
 
   private:
     // Returns true if this node has a current writing node with no children.
@@ -324,24 +302,15 @@
 
     void onWriteImpl(CommandGraphNode *writingNode, Serial currentSerial);
 
+    Serial mStoredQueueSerial;
+
     std::vector<CommandGraphNode *> mCurrentReadingNodes;
-};
 
-// Specialized command graph node for queries. Not for use with any exposed command buffers.
-class QueryGraphResource : public CommandGraphResource
-{
-  public:
-    ~QueryGraphResource() override;
+    // Current command graph writing node.
+    CommandGraphNode *mCurrentWritingNode;
 
-    void beginQuery(Context *context, const QueryPool *queryPool, uint32_t queryIndex);
-    void endQuery(Context *context, const QueryPool *queryPool, uint32_t queryIndex);
-    void writeTimestamp(Context *context, const QueryPool *queryPool, uint32_t queryIndex);
-
-  protected:
-    QueryGraphResource();
-
-  private:
-    void startNewCommands(RendererVk *renderer, CommandGraphNodeFunction function);
+    // Additional diagnostic information.
+    CommandGraphResourceType mResourceType;
 };
 
 // Translating OpenGL commands into Vulkan and submitting them immediately loses out on some
@@ -385,15 +354,21 @@
     bool empty() const;
     void clear();
 
-    CommandGraphNode *getLastBarrierNode(size_t *indexOut);
-
-    void setNewBarrier(CommandGraphNode *newBarrier);
+    // The following create special-function nodes that don't require a graph resource.
+    // Queries:
+    void beginQuery(const QueryPool *queryPool, uint32_t queryIndex);
+    void endQuery(const QueryPool *queryPool, uint32_t queryIndex);
+    void writeTimestamp(const QueryPool *queryPool, uint32_t queryIndex);
 
   private:
-    void dumpGraphDotFile(std::ostream &out) const;
-
+    CommandGraphNode *allocateBarrierNode(CommandGraphResourceType resourceType,
+                                          CommandGraphNodeFunction function);
+    void setNewBarrier(CommandGraphNode *newBarrier);
+    CommandGraphNode *getLastBarrierNode(size_t *indexOut);
     void addDependenciesToNextBarrier(size_t begin, size_t end, CommandGraphNode *nextBarrier);
 
+    void dumpGraphDotFile(std::ostream &out) const;
+
     std::vector<CommandGraphNode *> mNodes;
     bool mEnableGraphDiagnostics;
 
diff --git a/src/libANGLE/renderer/vulkan/QueryVk.cpp b/src/libANGLE/renderer/vulkan/QueryVk.cpp
index 9e21117..c321402 100644
--- a/src/libANGLE/renderer/vulkan/QueryVk.cpp
+++ b/src/libANGLE/renderer/vulkan/QueryVk.cpp
@@ -50,13 +50,11 @@
                 contextVk, &mQueryHelperTimeElapsedBegin));
         }
 
-        mQueryHelperTimeElapsedBegin.writeTimestamp(contextVk,
-                                                    mQueryHelperTimeElapsedBegin.getQueryPool(),
-                                                    mQueryHelperTimeElapsedBegin.getQuery());
+        mQueryHelperTimeElapsedBegin.writeTimestamp(contextVk);
     }
     else
     {
-        mQueryHelper.beginQuery(contextVk, mQueryHelper.getQueryPool(), mQueryHelper.getQuery());
+        mQueryHelper.beginQuery(contextVk);
     }
 
     return angle::Result::Continue;
@@ -68,12 +66,11 @@
 
     if (getType() == gl::QueryType::TimeElapsed)
     {
-        mQueryHelper.writeTimestamp(contextVk, mQueryHelper.getQueryPool(),
-                                    mQueryHelper.getQuery());
+        mQueryHelper.writeTimestamp(contextVk);
     }
     else
     {
-        mQueryHelper.endQuery(contextVk, mQueryHelper.getQueryPool(), mQueryHelper.getQuery());
+        mQueryHelper.endQuery(contextVk);
     }
 
     return angle::Result::Continue;
@@ -92,7 +89,7 @@
 
     ASSERT(getType() == gl::QueryType::Timestamp);
 
-    mQueryHelper.writeTimestamp(contextVk, mQueryHelper.getQueryPool(), mQueryHelper.getQuery());
+    mQueryHelper.writeTimestamp(contextVk);
 
     return angle::Result::Continue;
 }
@@ -123,7 +120,7 @@
     // may not have been performed by the GPU yet.  To avoid a race condition in this case, wait
     // for the batch to finish first before querying (or return not-ready if not waiting).
     ANGLE_TRY(renderer->checkCompletedCommands(contextVk));
-    if (mQueryHelper.isResourceInUse(renderer))
+    if (renderer->isSerialInUse(mQueryHelper.getStoredQueueSerial()))
     {
         if (!wait)
         {
diff --git a/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp b/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp
index c6158a2..a94943f 100644
--- a/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp
@@ -117,7 +117,7 @@
     mOwner     = nullptr;
 }
 
-vk::ImageHelper *RenderTargetVk::getImageForRead(vk::RecordableGraphResource *readingResource,
+vk::ImageHelper *RenderTargetVk::getImageForRead(vk::CommandGraphResource *readingResource,
                                                  VkImageLayout layout,
                                                  vk::CommandBuffer *commandBuffer)
 {
@@ -133,8 +133,7 @@
     return mImage;
 }
 
-vk::ImageHelper *RenderTargetVk::getImageForWrite(
-    vk::RecordableGraphResource *writingResource) const
+vk::ImageHelper *RenderTargetVk::getImageForWrite(vk::CommandGraphResource *writingResource) const
 {
     ASSERT(mImage && mImage->valid());
     mImage->addWriteDependency(writingResource);
diff --git a/src/libANGLE/renderer/vulkan/RenderTargetVk.h b/src/libANGLE/renderer/vulkan/RenderTargetVk.h
index ee15a2f..e231879 100644
--- a/src/libANGLE/renderer/vulkan/RenderTargetVk.h
+++ b/src/libANGLE/renderer/vulkan/RenderTargetVk.h
@@ -24,7 +24,7 @@
 class FramebufferHelper;
 class ImageHelper;
 class ImageView;
-class RecordableGraphResource;
+class CommandGraphResource;
 class RenderPassDesc;
 }  // namespace vk
 
@@ -58,10 +58,10 @@
     const vk::ImageHelper &getImage() const;
 
     // getImageForRead will also transition the resource to the given layout.
-    vk::ImageHelper *getImageForRead(vk::RecordableGraphResource *readingResource,
+    vk::ImageHelper *getImageForRead(vk::CommandGraphResource *readingResource,
                                      VkImageLayout layout,
                                      vk::CommandBuffer *commandBuffer);
-    vk::ImageHelper *getImageForWrite(vk::RecordableGraphResource *writingResource) const;
+    vk::ImageHelper *getImageForWrite(vk::CommandGraphResource *writingResource) const;
 
     vk::ImageView *getDrawImageView() const;
     vk::ImageView *getReadImageView() const;
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.h b/src/libANGLE/renderer/vulkan/VertexArrayVk.h
index 835333c..4056e16 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.h
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.h
@@ -18,11 +18,6 @@
 {
 class BufferVk;
 
-namespace vk
-{
-class RecordableGraphResource;
-}  // namespace vk
-
 class VertexArrayVk : public VertexArrayImpl
 {
   public:
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
index 8f62394..e626005 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp
@@ -629,9 +629,7 @@
 }
 
 // QueryHelper implementation
-QueryHelper::QueryHelper()
-    : QueryGraphResource(), mDynamicQueryPool(nullptr), mQueryPoolIndex(0), mQuery(0)
-{}
+QueryHelper::QueryHelper() : mDynamicQueryPool(nullptr), mQueryPoolIndex(0), mQuery(0) {}
 
 QueryHelper::~QueryHelper() {}
 
@@ -651,6 +649,34 @@
     mQuery            = 0;
 }
 
+void QueryHelper::beginQuery(vk::Context *context)
+{
+    RendererVk *renderer = context->getRenderer();
+    renderer->getCommandGraph()->beginQuery(getQueryPool(), getQuery());
+    mMostRecentSerial = renderer->getCurrentQueueSerial();
+}
+
+void QueryHelper::endQuery(vk::Context *context)
+{
+    RendererVk *renderer = context->getRenderer();
+    renderer->getCommandGraph()->endQuery(getQueryPool(), getQuery());
+    mMostRecentSerial = renderer->getCurrentQueueSerial();
+}
+
+void QueryHelper::writeTimestamp(vk::Context *context)
+{
+    RendererVk *renderer = context->getRenderer();
+    renderer->getCommandGraph()->writeTimestamp(getQueryPool(), getQuery());
+    mMostRecentSerial = renderer->getCurrentQueueSerial();
+}
+
+bool QueryHelper::hasPendingWork(RendererVk *renderer)
+{
+    // If the renderer has a queue serial higher than the stored one, the command buffers that
+    // recorded this query have already been submitted, so there is no pending work.
+    return mMostRecentSerial == renderer->getCurrentQueueSerial();
+}
+
 // DynamicSemaphorePool implementation
 DynamicSemaphorePool::DynamicSemaphorePool() = default;
 
@@ -912,7 +938,7 @@
 
 // BufferHelper implementation.
 BufferHelper::BufferHelper()
-    : RecordableGraphResource(CommandGraphResourceType::Buffer),
+    : CommandGraphResource(CommandGraphResourceType::Buffer),
       mMemoryPropertyFlags{},
       mSize(0),
       mMappedMemory(nullptr),
@@ -1068,7 +1094,7 @@
 
 // ImageHelper implementation.
 ImageHelper::ImageHelper()
-    : RecordableGraphResource(CommandGraphResourceType::Image),
+    : CommandGraphResource(CommandGraphResourceType::Image),
       mFormat(nullptr),
       mSamples(0),
       mCurrentLayout(VK_IMAGE_LAYOUT_UNDEFINED),
@@ -1077,7 +1103,7 @@
 {}
 
 ImageHelper::ImageHelper(ImageHelper &&other)
-    : RecordableGraphResource(CommandGraphResourceType::Image),
+    : CommandGraphResource(CommandGraphResourceType::Image),
       mImage(std::move(other.mImage)),
       mDeviceMemory(std::move(other.mDeviceMemory)),
       mExtents(other.mExtents),
@@ -1549,8 +1575,7 @@
 }
 
 // FramebufferHelper implementation.
-FramebufferHelper::FramebufferHelper()
-    : RecordableGraphResource(CommandGraphResourceType::Framebuffer)
+FramebufferHelper::FramebufferHelper() : CommandGraphResource(CommandGraphResourceType::Framebuffer)
 {}
 
 FramebufferHelper::~FramebufferHelper() = default;
diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.h b/src/libANGLE/renderer/vulkan/vk_helpers.h
index a131ae4..2ab9a2a 100644
--- a/src/libANGLE/renderer/vulkan/vk_helpers.h
+++ b/src/libANGLE/renderer/vulkan/vk_helpers.h
@@ -251,11 +251,11 @@
 // of a fixed size as needed and allocates indices within those pools.
 //
 // The QueryHelper class below keeps the pool and index pair together.
-class QueryHelper final : public QueryGraphResource
+class QueryHelper final
 {
   public:
     QueryHelper();
-    ~QueryHelper() override;
+    ~QueryHelper();
 
     void init(const DynamicQueryPool *dynamicQueryPool,
               const size_t queryPoolIndex,
@@ -271,10 +271,18 @@
     // Used only by DynamicQueryPool.
     size_t getQueryPoolIndex() const { return mQueryPoolIndex; }
 
+    void beginQuery(vk::Context *context);
+    void endQuery(vk::Context *context);
+    void writeTimestamp(vk::Context *context);
+
+    Serial getStoredQueueSerial() { return mMostRecentSerial; }
+    bool hasPendingWork(RendererVk *renderer);
+
   private:
     const DynamicQueryPool *mDynamicQueryPool;
     size_t mQueryPoolIndex;
     uint32_t mQuery;
+    Serial mMostRecentSerial;
 };
 
 // DynamicSemaphorePool allocates semaphores as needed.  It uses a std::vector
@@ -375,7 +383,7 @@
 
 class FramebufferHelper;
 
-class BufferHelper final : public RecordableGraphResource
+class BufferHelper final : public CommandGraphResource
 {
   public:
     BufferHelper();
@@ -392,7 +400,7 @@
     const DeviceMemory &getDeviceMemory() const { return mDeviceMemory; }
 
     // Helpers for setting the graph dependencies *and* setting the appropriate barrier.
-    ANGLE_INLINE void onRead(RecordableGraphResource *reader, VkAccessFlagBits readAccessType)
+    ANGLE_INLINE void onRead(CommandGraphResource *reader, VkAccessFlagBits readAccessType)
     {
         addReadDependency(reader);
 
@@ -462,7 +470,7 @@
     VkFlags mCurrentReadAccess;
 };
 
-class ImageHelper final : public RecordableGraphResource
+class ImageHelper final : public CommandGraphResource
 {
   public:
     ImageHelper();
@@ -583,7 +591,7 @@
     uint32_t mLevelCount;
 };
 
-class FramebufferHelper : public RecordableGraphResource
+class FramebufferHelper : public CommandGraphResource
 {
   public:
     FramebufferHelper();