text: /*
   * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
   * 
   * SPDX-License-Identifier: Apache-2.0 OR MIT
   *
   */
  #pragma once
  
  #include <RHI/ResourcePoolResolver.h>
  #include <AzCore/Memory/PoolAllocator.h>
  #include <RHI/Fence.h>
  
  namespace AZ
  {
      namespace DX12
      {
          class Device;
          class QueryPool;
          class Buffer;
  
          /**
          *   Resolve queries from a QueryPool into a buffer.
          */
          class QueryPoolResolver final
              : public ResourcePoolResolver
          {
              using Base = ResourcePoolResolver;
          public:
              AZ_RTTI(QueryPoolResolver, "{90CD6495-0758-4ED2-8B95-D5C5DE80CEBC}", Base);
              AZ_CLASS_ALLOCATOR(QueryPoolResolver, AZ::SystemAllocator, 0);
  
              /// Request for a resolving part of the QueryPool into a buffer.
              struct ResolveRequest
              {
                  uint32_t m_firstQuery = 0;
                  uint32_t m_queryCount = 0;
                  ID3D12Resource* m_resolveBuffer = nullptr;
                  uint64_t m_offset = 0;
                  D3D12_QUERY_TYPE m_queryType = D3D12_QUERY_TYPE_OCCLUSION;
              };
  
              QueryPoolResolver(Device& device, QueryPool& queryPool);
              virtual ~QueryPoolResolver() = default;
  
              /*  Queues a request for resolving a QueryPool. This will be processed during the resolve phase.
              *   @param request The request to be queue.
              *   @return Returns a fence value used for checking if the resolve has finished.
              */
              uint64_t QueueResolveRequest(const ResolveRequest& request);
  
              /// Check if a certan request has finished.
              bool IsResolveFinished(uint64_t fenceValue);
              /// Blocks until the request have finished.
              void WaitForResolve(uint64_t fenceValue);
  
          private:
  
              void Compile(Scope& scope);
              void Resolve(CommandList& commandList) const override;
              void Deactivate() override;
  
              QueryPool& m_queryPool; ///< Query pool that is being resolved.
              Device& m_device;
              AZStd::vector<ResolveRequest> m_resolveRequests; /// List of requests to be resolved.
  
              RHI::Ptr<FenceImpl> m_resolveFence; ///< Fence used for checking if a request has finished.
          };
      }
  }
  