Files
UnrealEngine/Engine/Source/Runtime/Apple/MetalRHI/Private/MetalBindlessDescriptors.h
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

130 lines
3.6 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "MetalRHIPrivate.h"
#if PLATFORM_SUPPORTS_BINDLESS_RENDERING
#include "MetalResources.h"
#include "MetalShaderResources.h"
#include "RHIDescriptorAllocator.h"
class FMetalCommandEncoder;
class FMetalDevice;
struct IRDescriptorTableEntry;
enum class EMetalDescriptorUpdateType
{
Immediate,
GPU,
};
struct FMetalPendingDescriptorUpdates
{
TArray<uint32> Indices;
TArray<IRDescriptorTableEntry> Descriptors;
int32 Num() const
{
return Indices.Num();
}
void Add(FRHIDescriptorHandle InHandle, const IRDescriptorTableEntry& InDescriptor)
{
if (ensure(InHandle.IsValid()))
{
Indices.Emplace(InHandle.GetIndex());
Descriptors.Emplace(InDescriptor);
}
}
void Empty()
{
Indices.Empty();
Descriptors.Empty();
}
};
struct FMetalDescriptorHeap
{
FMetalDescriptorHeap(FMetalDevice& MetalDevice, ERHIDescriptorTypeMask InTypeMask);
~FMetalDescriptorHeap();
void Init(FRHICommandListBase& RHICmdList, int32 HeapSize);
FRHIDescriptorHandle AllocateDescriptor(ERHIDescriptorType DescriptorType);
FRHIDescriptorHandle AllocateDescriptor(ERHIDescriptorType DescriptorType, IRDescriptorTableEntry DescriptorData);
void FreeDescriptor(FRHIDescriptorHandle DescriptorHandle);
void UpdateDescriptorImmediately(FRHIDescriptorHandle DescriptorHandle, IRDescriptorTableEntry DescriptorData);
void BindToEncoder(FMetalCommandEncoder* Encoder, MTL::FunctionType FunctionType, uint32 BindIndex);
ERHIDescriptorTypeMask GetTypeMask() const
{
return TypeMask;
}
bool HandlesAllocation(ERHIDescriptorType InType) const
{
return EnumHasAnyFlags(GetTypeMask(), RHIDescriptorTypeMaskFromType(InType));
}
FMetalRHIBuffer* GetHeap() const
{
return ResourceHeap.GetReference();
}
private:
IRDescriptorTableEntry* GetDescriptorMemory()
{
checkSlow(ResourceHeap != nullptr);
return reinterpret_cast<IRDescriptorTableEntry*>(ResourceHeap->GetCurrentBuffer()->Contents());
}
FMetalDevice& Device;
FRHIHeapDescriptorAllocator* Manager = nullptr;
TRefCountPtr<FMetalRHIBuffer> ResourceHeap;
const ERHIDescriptorTypeMask TypeMask;
};
class FMetalBindlessDescriptorManager
{
public:
FMetalBindlessDescriptorManager(FMetalDevice& MetalDevice);
~FMetalBindlessDescriptorManager();
void Init();
FRHIDescriptorHandle AllocateDescriptor(ERHIDescriptorType DescriptorType);
FRHIDescriptorHandle AllocateDescriptor(ERHIDescriptorType DescriptorType, MTL::Texture* Texture);
FRHIDescriptorHandle AllocateDescriptor(ERHIDescriptorType DescriptorType, FMetalBuffer* Buffer, const uint32_t ExtraOffset = 0);
FRHIDescriptorHandle AllocateDescriptor(MTL::SamplerState* SamplerState);
void FreeDescriptor(FRHIDescriptorHandle DescriptorHandle);
void UpdateDescriptor(FRHICommandListBase& RHICmdList, FRHIDescriptorHandle DescriptorHandle, MTL::Texture* Texture, EMetalDescriptorUpdateType UpdateType);
void UpdateDescriptor(FMetalRHICommandContext* Context, FRHIDescriptorHandle DescriptorHandle, FMetalResourceViewBase* Resource, EMetalDescriptorUpdateType UpdateType);
void FlushPendingDescriptorUpdates(FMetalRHICommandContext& Context, const FMetalPendingDescriptorUpdates& PendingDescriptorUpdates);
void BindDescriptorHeapsToEncoder(FMetalCommandEncoder* Encoder, MTL::FunctionType FunctionType, EMetalShaderStages Frequency);
bool IsSupported() const
{
return bIsSupported;
}
private:
FMetalDevice& Device;
FMetalDescriptorHeap StandardResources;
FMetalDescriptorHeap SamplerResources;
bool bIsSupported = false;
};
#endif