Files
UnrealEngine/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalRHIRenderQuery.h
2025-05-18 13:04:45 +08:00

151 lines
3.5 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
MetalRHIRenderQuery.h: Metal RHI Render Query Definitions.
=============================================================================*/
#pragma once
#include "MetalRHIPrivate.h"
#include "RHIResources.h"
#include "MetalSubmission.h"
//------------------------------------------------------------------------------
#pragma mark - Metal RHI Private Query Buffer Forward Declarations
class FMetalRHICommandContext;
class FMetalQueryBufferPool;
class FMetalQueryResult;
class FMetalDevice;
class FMetalBuffer;
typedef TSharedPtr<FMetalBuffer, ESPMode::ThreadSafe> FMetalBufferPtr;
//------------------------------------------------------------------------------
#pragma mark - Metal RHI Private Query Buffer Resource Class -
class FMetalQueryBuffer : public FRHIResource
{
public:
FMetalQueryBuffer(FMetalQueryBufferPool* Pool, FMetalBufferPtr InBuffer);
virtual ~FMetalQueryBuffer();
uint64 GetResult(uint32 Offset);
FMetalQueryBufferPool* Pool;
FMetalBufferPtr Buffer;
uint32 WriteOffset;
};
//------------------------------------------------------------------------------
#pragma mark - Metal RHI Private Query Buffer Pool Class -
class FMetalQueryBufferPool
{
public:
enum
{
EQueryBufferAlignment = 8,
EQueryResultMaxSize = 8
};
// Disallow a default constructor
FMetalQueryBufferPool() = delete;
FMetalQueryBufferPool(FMetalDevice& InDevice);
~FMetalQueryBufferPool();
void Allocate(FMetalQueryResult& NewQuery);
FMetalQueryBuffer* AcquireQueryBuffer(uint32_t NumOcclusionQueries);
FMetalQueryBuffer* GetCurrentQueryBuffer();
void ReleaseCurrentQueryBuffer();
void ReleaseQueryBuffer(FMetalBufferPtr Buffer);
uint32_t BufferSize = 0;
TRefCountPtr<FMetalQueryBuffer> CurrentBuffer;
TArray<FMetalBufferPtr> Buffers;
FMetalDevice& Device;
};
//------------------------------------------------------------------------------
#pragma mark - Metal RHI Private Query Result Class -
class FMetalQueryResult
{
public:
FMetalQueryResult() = default;
~FMetalQueryResult() = default;
void Reset();
uint64 GetResult();
TRefCountPtr<FMetalQueryBuffer> SourceBuffer = nullptr;
uint32 Offset = 0;
bool bCompleted = false;
bool bBatchFence = false;
};
//------------------------------------------------------------------------------
#pragma mark - Metal RHI Render Query Class -
class FMetalRHIRenderQuery : public FRHIRenderQuery
{
friend class FMetalDynamicRHI;
public:
FMetalRHIRenderQuery(FMetalDevice& MetalDevice, ERenderQueryType InQueryType);
virtual ~FMetalRHIRenderQuery();
void Begin_TopOfPipe();
void End_TopOfPipe();
/**
* Kick off an occlusion test
*/
void Begin(FMetalRHICommandContext* Context);
/**
* Finish up an occlusion test
*/
void End(FMetalRHICommandContext* Context);
/**
* Get the query result
*/
bool GetResult(uint64& OutNumPixels, bool bWait, uint32 GPUIndex);
private:
FMetalDevice& Device;
// The type of query
ERenderQueryType Type;
// Query buffer allocation details as the buffer is already set on the command-encoder
FMetalQueryResult Buffer;
// Query result.
volatile uint64 Result;
// Result availability - if not set the first call to acquire it will read the buffer & cache
std::atomic<bool> bAvailable;
// Signaled when the result is available. Nullptr if the query has never been used.
FMetalSyncPointRef SyncPoint;
// Temporary
FMetalCommandBuffer* CommandBuffer = nullptr;
};