839 lines
37 KiB
C++
839 lines
37 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
OpenGLDrv.h: Public OpenGL RHI definitions.
|
|
=============================================================================*/
|
|
|
|
#pragma once
|
|
|
|
// Dependencies.
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Containers/IndirectArray.h"
|
|
#include "IOpenGLDynamicRHI.h"
|
|
#include "RHIDefinitions.h"
|
|
#include "RHI.h"
|
|
#include "GPUProfiler.h"
|
|
#include "RenderResource.h"
|
|
#include "Templates/EnableIf.h"
|
|
#include "BoundShaderStateHistory.h"
|
|
|
|
#include "OpenGLState.h"
|
|
#include "OpenGLPlatform.h"
|
|
#include "OpenGLUtil.h"
|
|
#include "RenderUtils.h"
|
|
|
|
// Define here so don't have to do platform filtering
|
|
#ifndef GL_TEXTURE_EXTERNAL_OES
|
|
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
|
|
#endif
|
|
|
|
#define FOpenGLCachedUniformBuffer_Invalid 0xFFFFFFFF
|
|
|
|
template<class T> struct TOpenGLResourceTraits;
|
|
|
|
#if (RHI_NEW_GPU_PROFILER == 0)
|
|
|
|
// This class has multiple inheritance but really FGPUTiming is a static class
|
|
class FOpenGLBufferedGPUTiming : public FGPUTiming
|
|
{
|
|
public:
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param InOpenGLRHI RHI interface
|
|
* @param InBufferSize Number of buffered measurements
|
|
*/
|
|
FOpenGLBufferedGPUTiming(int32 BufferSize);
|
|
|
|
void StartTiming();
|
|
|
|
/**
|
|
* End a GPU timing measurement.
|
|
* The timing for this particular measurement will be resolved at a later time by the GPU.
|
|
*/
|
|
void EndTiming();
|
|
|
|
/**
|
|
* Retrieves the most recently resolved timing measurement.
|
|
* The unit is the same as for FPlatformTime::Cycles(). Returns 0 if there are no resolved measurements.
|
|
*
|
|
* @return Value of the most recently resolved timing, or 0 if no measurements have been resolved by the GPU yet.
|
|
*/
|
|
uint64 GetTiming(bool bGetCurrentResultsAndBlock = false);
|
|
|
|
void InitResources();
|
|
void ReleaseResources();
|
|
|
|
|
|
private:
|
|
|
|
/**
|
|
* Initializes the static variables, if necessary.
|
|
*/
|
|
static void PlatformStaticInitialize(void* UserData);
|
|
|
|
/** Number of timestamps created in 'StartTimestamps' and 'EndTimestamps'. */
|
|
const int32 BufferSize;
|
|
/** Current timing being measured on the CPU. */
|
|
int32 CurrentTimestamp = -1;
|
|
/** Number of measurements in the buffers (0 - BufferSize). */
|
|
int32 NumIssuedTimestamps = 0;
|
|
/** Timestamps for all StartTimings. */
|
|
TArray<FOpenGLRenderQuery *> StartTimestamps;
|
|
/** Timestamps for all EndTimings. */
|
|
TArray<FOpenGLRenderQuery *> EndTimestamps;
|
|
/** Whether we are currently timing the GPU: between StartTiming() and EndTiming(). */
|
|
bool bIsTiming = false;
|
|
};
|
|
|
|
/**
|
|
* Used to track whether a period was disjoint on the GPU, which means GPU timings are invalid.
|
|
* OpenGL lacks this concept at present, so the class is just a placeholder
|
|
* Timings are all assumed to be non-disjoint
|
|
*/
|
|
class FOpenGLDisjointTimeStampQuery
|
|
{
|
|
public:
|
|
FOpenGLDisjointTimeStampQuery()
|
|
: DisjointQuery(new FOpenGLRenderQuery { FOpenGLRenderQuery::EType::Disjoint })
|
|
{}
|
|
|
|
void StartTracking();
|
|
void EndTracking();
|
|
bool IsResultValid();
|
|
|
|
bool GetResult(uint64* OutResult);
|
|
|
|
static uint64 GetTimingFrequency()
|
|
{
|
|
return 1000000000ull;
|
|
}
|
|
|
|
static bool IsSupported()
|
|
{
|
|
#if UE_BUILD_SHIPPING
|
|
return false;
|
|
#else
|
|
return FOpenGL::SupportsDisjointTimeQueries();
|
|
#endif
|
|
}
|
|
|
|
void Cleanup()
|
|
{
|
|
delete DisjointQuery;
|
|
DisjointQuery = nullptr;
|
|
}
|
|
|
|
private:
|
|
bool bIsResultValid = false;
|
|
FOpenGLRenderQuery* DisjointQuery;
|
|
};
|
|
|
|
/** A single perf event node, which tracks information about a appBeginDrawEvent/appEndDrawEvent range. */
|
|
class FOpenGLEventNode : public FGPUProfilerEventNode
|
|
{
|
|
public:
|
|
|
|
FOpenGLEventNode(const TCHAR* InName, FGPUProfilerEventNode* InParent)
|
|
: FGPUProfilerEventNode(InName, InParent)
|
|
, Timing(1)
|
|
{
|
|
// Initialize Buffered timestamp queries
|
|
Timing.InitResources();
|
|
}
|
|
|
|
virtual ~FOpenGLEventNode()
|
|
{
|
|
Timing.ReleaseResources();
|
|
}
|
|
|
|
/**
|
|
* Returns the time in ms that the GPU spent in this draw event.
|
|
* This blocks the CPU if necessary, so can cause hitching.
|
|
*/
|
|
float GetTiming() override;
|
|
|
|
virtual void StartTiming() override
|
|
{
|
|
Timing.StartTiming();
|
|
}
|
|
|
|
virtual void StopTiming() override
|
|
{
|
|
Timing.EndTiming();
|
|
}
|
|
|
|
FOpenGLBufferedGPUTiming Timing;
|
|
};
|
|
|
|
/** An entire frame of perf event nodes, including ancillary timers. */
|
|
class FOpenGLEventNodeFrame : public FGPUProfilerEventNodeFrame
|
|
{
|
|
public:
|
|
FOpenGLEventNodeFrame()
|
|
: RootEventTiming(1)
|
|
, DisjointQuery()
|
|
{
|
|
RootEventTiming.InitResources();
|
|
}
|
|
|
|
~FOpenGLEventNodeFrame()
|
|
{
|
|
RootEventTiming.ReleaseResources();
|
|
}
|
|
|
|
/** Start this frame of per tracking */
|
|
void StartFrame() override;
|
|
|
|
/** End this frame of per tracking, but do not block yet */
|
|
void EndFrame() override;
|
|
|
|
/** Calculates root timing base frequency (if needed by this RHI) */
|
|
virtual float GetRootTimingResults() override;
|
|
|
|
virtual void LogDisjointQuery() override;
|
|
|
|
/** Timer tracking inclusive time spent in the root nodes. */
|
|
FOpenGLBufferedGPUTiming RootEventTiming;
|
|
|
|
/** Disjoint query tracking whether the times reported by DumpEventTree are reliable. */
|
|
FOpenGLDisjointTimeStampQuery DisjointQuery;
|
|
};
|
|
|
|
/**
|
|
* Encapsulates GPU profiling logic and data.
|
|
* There's only one global instance of this struct so it should only contain global data, nothing specific to a frame.
|
|
*/
|
|
struct FOpenGLGPUProfiler : public FGPUProfiler
|
|
{
|
|
/** Used to measure GPU time per frame. */
|
|
FOpenGLBufferedGPUTiming FrameTiming;
|
|
|
|
/** Measuring GPU frame time with a disjoint query. */
|
|
static const int MAX_GPUFRAMEQUERIES = 4;
|
|
FOpenGLDisjointTimeStampQuery DisjointGPUFrameTimeQuery[MAX_GPUFRAMEQUERIES];
|
|
int32 CurrentGPUFrameQueryIndex = 0;
|
|
|
|
// count the number of beginframe calls without matching endframe calls.
|
|
int32 NestedFrameCount = 0;
|
|
|
|
uint32 ExternalGPUTime = 0;
|
|
|
|
/** GPU hitch profile histories */
|
|
TIndirectArray<FOpenGLEventNodeFrame> GPUHitchEventNodeFrames;
|
|
|
|
FOpenGLGPUProfiler()
|
|
: FrameTiming(4)
|
|
{
|
|
FrameTiming.InitResources();
|
|
BeginFrame();
|
|
}
|
|
|
|
virtual FGPUProfilerEventNode* CreateEventNode(const TCHAR* InName, FGPUProfilerEventNode* InParent) override
|
|
{
|
|
FOpenGLEventNode* EventNode = new FOpenGLEventNode(InName, InParent);
|
|
return EventNode;
|
|
}
|
|
|
|
void Cleanup();
|
|
|
|
void BeginFrame();
|
|
void EndFrame();
|
|
};
|
|
|
|
#endif // (RHI_NEW_GPU_PROFILER == 0)
|
|
|
|
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
|
|
|
/** The interface which is implemented by the dynamically bound RHI. */
|
|
class OPENGLDRV_API FOpenGLDynamicRHI final : public IOpenGLDynamicRHI, public IRHICommandContextPSOFallback
|
|
{
|
|
static inline FOpenGLDynamicRHI* Singleton = nullptr;
|
|
|
|
public:
|
|
static inline FOpenGLDynamicRHI& Get() { return *Singleton; }
|
|
|
|
friend class FOpenGLViewport;
|
|
|
|
/** Initialization constructor. */
|
|
FOpenGLDynamicRHI();
|
|
|
|
/** Destructor */
|
|
~FOpenGLDynamicRHI() {}
|
|
|
|
// IOpenGLDynamicRHI interface.
|
|
virtual int32 RHIGetGLMajorVersion() const final override;
|
|
virtual int32 RHIGetGLMinorVersion() const final override;
|
|
virtual bool RHISupportsFramebufferSRGBEnable() const final override;
|
|
virtual FTextureRHIRef RHICreateTexture2DFromResource(EPixelFormat Format, uint32 SizeX, uint32 SizeY, uint32 NumMips, uint32 NumSamples, uint32 NumSamplesTileMem, const FClearValueBinding& ClearValueBinding, GLuint Resource, ETextureCreateFlags Flags) final override;
|
|
#if PLATFORM_ANDROID
|
|
virtual FTextureRHIRef RHICreateTexture2DFromAndroidHardwareBuffer(FRHICommandListBase& RHICmdList, AHardwareBuffer* HardwareBuffer) override;
|
|
#endif //PLATFORM_ANDROID
|
|
|
|
virtual FTextureRHIRef RHICreateTexture2DArrayFromResource(EPixelFormat Format, uint32 SizeX, uint32 SizeY, uint32 ArraySize, uint32 NumMips, uint32 NumSamples, uint32 NumSamplesTileMem, const FClearValueBinding& ClearValueBinding, GLuint Resource, ETextureCreateFlags Flags) final override;
|
|
virtual FTextureRHIRef RHICreateTextureCubeFromResource(EPixelFormat Format, uint32 Size, bool bArray, uint32 ArraySize, uint32 NumMips, uint32 NumSamples, uint32 NumSamplesTileMem, const FClearValueBinding& ClearValueBinding, GLuint Resource, ETextureCreateFlags Flags) final override;
|
|
virtual GLuint RHIGetResource(FRHITexture* InTexture) const final override;
|
|
virtual bool RHIIsValidTexture(GLuint InTexture) const final override;
|
|
virtual void RHISetExternalGPUTime(uint64 InExternalGPUTime) final override;
|
|
|
|
#if PLATFORM_ANDROID
|
|
virtual EGLDisplay RHIGetEGLDisplay() const final override;
|
|
virtual EGLSurface RHIGetEGLSurface() const final override;
|
|
virtual EGLConfig RHIGetEGLConfig() const final override;
|
|
virtual EGLContext RHIGetEGLContext() const final override;
|
|
virtual ANativeWindow* RHIGetEGLNativeWindow() const final override;
|
|
virtual bool RHIEGLSupportsNoErrorContext() const final override;
|
|
virtual void RHIInitEGLInstanceGLES2() final override;
|
|
virtual void RHIInitEGLBackBuffer() final override;
|
|
virtual void RHIEGLSetCurrentRenderingContext() final override;
|
|
virtual void RHIEGLTerminateContext() final override;
|
|
#endif
|
|
|
|
// FDynamicRHI interface.
|
|
virtual void Init() override;
|
|
|
|
virtual void Shutdown() override;
|
|
virtual const TCHAR* GetName() override { return TEXT("OpenGL"); }
|
|
|
|
template<typename TRHIType>
|
|
static auto* ResourceCast(TRHIType* Resource)
|
|
{
|
|
return static_cast<typename TOpenGLResourceTraits<TRHIType>::TConcreteType*>(Resource);
|
|
}
|
|
|
|
static FOpenGLTexture* ResourceCast(FRHITexture* TextureRHI)
|
|
{
|
|
if (!TextureRHI)
|
|
{
|
|
return nullptr;
|
|
}
|
|
else
|
|
{
|
|
return static_cast<FOpenGLTexture*>(TextureRHI->GetTextureBaseRHI());
|
|
}
|
|
}
|
|
|
|
void BindUniformBuffer(EShaderFrequency ShaderFrequency, uint32 BufferIndex, FRHIUniformBuffer* BufferRHI);
|
|
|
|
void SetShaderParametersCommon(EShaderFrequency ShaderFrequency, TConstArrayView<uint8> InParametersData, TConstArrayView<FRHIShaderParameter> InParameters, TConstArrayView<FRHIShaderParameterResource> InResourceParameters);
|
|
void SetShaderUnbindsCommon(EShaderFrequency ShaderFrequency, TConstArrayView<FRHIShaderParameterUnbind> InUnbinds);
|
|
|
|
virtual FRasterizerStateRHIRef RHICreateRasterizerState(const FRasterizerStateInitializerRHI& Initializer) final override;
|
|
virtual FDepthStencilStateRHIRef RHICreateDepthStencilState(const FDepthStencilStateInitializerRHI& Initializer) final override;
|
|
virtual FBlendStateRHIRef RHICreateBlendState(const FBlendStateInitializerRHI& Initializer) final override;
|
|
virtual FVertexDeclarationRHIRef RHICreateVertexDeclaration(const FVertexDeclarationElementList& Elements) final override;
|
|
|
|
virtual FPixelShaderRHIRef RHICreatePixelShader(TArrayView<const uint8> Code, const FSHAHash& Hash) final override;
|
|
virtual FVertexShaderRHIRef RHICreateVertexShader(TArrayView<const uint8> Code, const FSHAHash& Hash) final override;
|
|
virtual FGeometryShaderRHIRef RHICreateGeometryShader(TArrayView<const uint8> Code, const FSHAHash& Hash) final override;
|
|
virtual FComputeShaderRHIRef RHICreateComputeShader(TArrayView<const uint8> Code, const FSHAHash& Hash) final override;
|
|
|
|
// SRV / UAV creation functions
|
|
virtual FShaderResourceViewRHIRef RHICreateShaderResourceView (class FRHICommandListBase& RHICmdList, FRHIViewableResource* Resource, FRHIViewDesc const& ViewDesc) final override;
|
|
virtual FUnorderedAccessViewRHIRef RHICreateUnorderedAccessView(class FRHICommandListBase& RHICmdList, FRHIViewableResource* Resource, FRHIViewDesc const& ViewDesc) final override;
|
|
|
|
virtual FUniformBufferRHIRef RHICreateUniformBuffer(const void* Contents, const FRHIUniformBufferLayout* Layout, EUniformBufferUsage Usage, EUniformBufferValidation Validation) final override;
|
|
virtual void RHIUpdateUniformBuffer(FRHICommandListBase& RHICmdList, FRHIUniformBuffer* UniformBufferRHI, const void* Contents) final override;
|
|
|
|
[[nodiscard]] virtual FRHIBufferInitializer RHICreateBufferInitializer(FRHICommandListBase& RHICmdList, const FRHIBufferCreateDesc& CreateDesc) final override;
|
|
|
|
virtual void RHIReplaceResources(FRHICommandListBase& RHICmdList, TArray<FRHIResourceReplaceInfo>&& ReplaceInfos) final override;
|
|
virtual void* LockBuffer_BottomOfPipe(FRHICommandListBase& RHICmdList, FRHIBuffer* Buffer, uint32 Offset, uint32 Size, EResourceLockMode LockMode) final override;
|
|
virtual void UnlockBuffer_BottomOfPipe(FRHICommandListBase& RHICmdList, FRHIBuffer* Buffer) final override;
|
|
#if ENABLE_LOW_LEVEL_MEM_TRACKER || UE_MEMORY_TRACE_ENABLED
|
|
virtual void RHIUpdateAllocationTags(FRHICommandListBase& RHICmdList, FRHIBuffer* Buffer) final override;
|
|
#endif
|
|
virtual FRHICalcTextureSizeResult RHICalcTexturePlatformSize(FRHITextureDesc const& Desc, uint32 FirstMipIndex) final override;
|
|
virtual void RHIGetTextureMemoryStats(FTextureMemoryStats& OutStats) final override;
|
|
virtual bool RHIGetTextureMemoryVisualizeData(FColor* TextureData,int32 SizeX,int32 SizeY,int32 Pitch,int32 PixelSize) final override;
|
|
[[nodiscard]] virtual FRHITextureInitializer RHICreateTextureInitializer(FRHICommandListBase& RHICmdList, const FRHITextureCreateDesc& CreateDesc) final override;
|
|
virtual FTextureRHIRef RHIAsyncCreateTexture2D(uint32 SizeX, uint32 SizeY, uint8 Format, uint32 NumMips, ETextureCreateFlags Flags, ERHIAccess InResourceState, void** InitialMipData, uint32 NumInitialMips, const TCHAR* DebugName, FGraphEventRef& OutCompletionEvent) final override;
|
|
virtual void RHIGenerateMips(FRHITexture* Texture) final override;
|
|
virtual uint32 RHIComputeMemorySize(FRHITexture* TextureRHI) final override;
|
|
virtual FTextureRHIRef RHIAsyncReallocateTexture2D(FRHITexture* Texture2D, int32 NewMipCount, int32 NewSizeX, int32 NewSizeY, FThreadSafeCounter* RequestStatus) final override;
|
|
|
|
virtual FRHILockTextureResult RHILockTexture(FRHICommandListImmediate& RHICmdList, const FRHILockTextureArgs& Arguments) final override;
|
|
virtual void RHIUnlockTexture(FRHICommandListImmediate& RHICmdList, const FRHILockTextureArgs& Arguments) final override;
|
|
|
|
virtual void RHIUpdateTexture2D(FRHICommandListBase& RHICmdList, FRHITexture* Texture, uint32 MipIndex, const struct FUpdateTextureRegion2D& UpdateRegion, uint32 SourcePitch, const uint8* SourceData) final override;
|
|
virtual void RHIUpdateTexture3D(FRHICommandListBase& RHICmdList, FRHITexture* Texture, uint32 MipIndex, const struct FUpdateTextureRegion3D& UpdateRegion, uint32 SourceRowPitch, uint32 SourceDepthPitch, const uint8* SourceData) final override;
|
|
virtual void RHIBindDebugLabelName(FRHICommandListBase& RHICmdList, FRHITexture* Texture, const TCHAR* Name) final override;
|
|
virtual void RHIReadSurfaceData(FRHITexture* Texture,FIntRect Rect,TArray<FColor>& OutData,FReadSurfaceDataFlags InFlags) final override;
|
|
virtual void RHIReadSurfaceData(FRHITexture* Texture, FIntRect Rect, TArray<FLinearColor>& OutData, FReadSurfaceDataFlags InFlags) final override;
|
|
virtual void RHIMapStagingSurface(FRHITexture* Texture, FRHIGPUFence* Fence, void*& OutData, int32& OutWidth, int32& OutHeight, uint32 GPUIndex = 0) final override;
|
|
virtual void RHIUnmapStagingSurface(FRHITexture* Texture, uint32 GPUIndex = 0) final override;
|
|
virtual void RHIReadSurfaceFloatData(FRHITexture* Texture,FIntRect Rect,TArray<FFloat16Color>& OutData,ECubeFace CubeFace,int32 ArrayIndex,int32 MipIndex) final override;
|
|
virtual void RHIRead3DSurfaceFloatData(FRHITexture* Texture,FIntRect Rect,FIntPoint ZMinMax,TArray<FFloat16Color>& OutData) final override;
|
|
virtual FRenderQueryRHIRef RHICreateRenderQuery(ERenderQueryType QueryType) final override;
|
|
virtual bool RHIGetRenderQueryResult(FRHIRenderQuery* RenderQuery, uint64& OutResult, bool bWait, uint32 GPUIndex = INDEX_NONE) final override;
|
|
virtual FTextureRHIRef RHIGetViewportBackBuffer(FRHIViewport* Viewport) final override;
|
|
virtual void RHIAliasTextureResources(FTextureRHIRef& DestTextureRHI, FTextureRHIRef& SrcTextureRHI) final override;
|
|
virtual FTextureRHIRef RHICreateAliasedTexture(FTextureRHIRef& SourceTexture) final override;
|
|
virtual void RHIAdvanceFrameForGetViewportBackBuffer(FRHIViewport* Viewport) final override;
|
|
virtual void RHIAcquireThreadOwnership() final override;
|
|
virtual void RHIReleaseThreadOwnership() final override;
|
|
virtual void RHIFlushResources() final override;
|
|
virtual FViewportRHIRef RHICreateViewport(void* WindowHandle, uint32 SizeX, uint32 SizeY, bool bIsFullscreen, EPixelFormat PreferredPixelFormat) final override;
|
|
virtual void RHIResizeViewport(FRHIViewport* Viewport, uint32 SizeX, uint32 SizeY, bool bIsFullscreen) final override;
|
|
virtual EPixelFormat RHIPreferredPixelFormatHint(EPixelFormat PreferredPixelFormat) final override;
|
|
virtual void RHITick(float DeltaTime) final override;
|
|
virtual void RHIBlockUntilGPUIdle() final override;
|
|
virtual bool RHIGetAvailableResolutions(FScreenResolutionArray& Resolutions, bool bIgnoreRefreshRate) final override;
|
|
virtual void RHIGetSupportedResolution(uint32& Width, uint32& Height) final override;
|
|
virtual void* RHIGetNativeDevice() final override;
|
|
virtual void* RHIGetNativeInstance() final override;
|
|
virtual class IRHICommandContext* RHIGetDefaultContext() final override;
|
|
virtual IRHIComputeContext* RHIGetCommandContext(ERHIPipeline Pipeline, FRHIGPUMask GPUMask) final override;
|
|
virtual void RHIFinalizeContext(FRHIFinalizeContextArgs&& Args, TRHIPipelineArray<IRHIPlatformCommandList*>& Output) final override;
|
|
virtual void RHISubmitCommandLists(FRHISubmitCommandListsArgs&& Args) final override;
|
|
|
|
virtual void RHIBeginRenderPass(const FRHIRenderPassInfo& InInfo, const TCHAR* InName) final override;
|
|
virtual void RHIEndRenderPass() final override;
|
|
virtual void RHINextSubpass() final override;
|
|
|
|
virtual void RHIBeginTransitions(TArrayView<const FRHITransition*> Transitions) override final;
|
|
virtual void RHIEndTransitions(TArrayView<const FRHITransition*> Transitions) override final;
|
|
|
|
virtual void RHISetComputeShader(FRHIComputeShader* ComputeShader) final override;
|
|
virtual void RHIDispatchComputeShader(uint32 ThreadGroupCountX, uint32 ThreadGroupCountY, uint32 ThreadGroupCountZ) final override;
|
|
virtual void RHIDispatchIndirectComputeShader(FRHIBuffer* ArgumentBuffer, uint32 ArgumentOffset) final override;
|
|
virtual void RHISetMultipleViewports(uint32 Count, const FViewportBounds* Data) final override;
|
|
virtual void RHIClearUAVFloat(FRHIUnorderedAccessView* UnorderedAccessViewRHI, const FVector4f& Values) final override;
|
|
virtual void RHIClearUAVUint(FRHIUnorderedAccessView* UnorderedAccessViewRHI, const FUintVector4& Values) final override;
|
|
|
|
virtual void RHIBeginRenderQuery_TopOfPipe(FRHICommandListBase& RHICmdList, FRHIRenderQuery* RenderQuery) override final;
|
|
virtual void RHIEndRenderQuery_TopOfPipe(FRHICommandListBase& RHICmdList, FRHIRenderQuery* RenderQuery) override final;
|
|
virtual void RHIBeginRenderQuery(FRHIRenderQuery* RenderQuery) final override;
|
|
virtual void RHIEndRenderQuery(FRHIRenderQuery* RenderQuery) final override;
|
|
|
|
virtual void RHIBeginDrawingViewport(FRHIViewport* Viewport, FRHITexture* RenderTargetRHI) final override;
|
|
virtual void RHIEndDrawingViewport(FRHIViewport* Viewport, bool bPresent, bool bLockToVsync) final override;
|
|
virtual void RHIEndFrame(const FRHIEndFrameArgs& Args) final override;
|
|
virtual void RHISetStreamSource(uint32 StreamIndex, FRHIBuffer* VertexBuffer, uint32 Offset) final override;
|
|
virtual void RHISetRasterizerState(FRHIRasterizerState* NewState) final override;
|
|
virtual void RHISetViewport(float MinX, float MinY, float MinZ, float MaxX, float MaxY, float MaxZ) final override;
|
|
virtual void RHISetScissorRect(bool bEnable, uint32 MinX, uint32 MinY, uint32 MaxX, uint32 MaxY) final override;
|
|
virtual void RHISetBoundShaderState(FRHIBoundShaderState* BoundShaderState) final override;
|
|
virtual void RHISetStaticUniformBuffers(const FUniformBufferStaticBindings& InUniformBuffers) final override;
|
|
virtual void RHISetStaticUniformBuffer(FUniformBufferStaticSlot Slot, FRHIUniformBuffer* Buffer) final override;
|
|
virtual void RHISetUniformBufferDynamicOffset(FUniformBufferStaticSlot Slot, uint32 Offset) final override;
|
|
virtual void RHISetShaderParameters(FRHIGraphicsShader* Shader, TConstArrayView<uint8> InParametersData, TConstArrayView<FRHIShaderParameter> InParameters, TConstArrayView<FRHIShaderParameterResource> InResourceParameters, TConstArrayView<FRHIShaderParameterResource> InBindlessParameters) final override;
|
|
virtual void RHISetShaderParameters(FRHIComputeShader* Shader, TConstArrayView<uint8> InParametersData, TConstArrayView<FRHIShaderParameter> InParameters, TConstArrayView<FRHIShaderParameterResource> InResourceParameters, TConstArrayView<FRHIShaderParameterResource> InBindlessParameters) final override;
|
|
virtual void RHISetShaderUnbinds(FRHIComputeShader* Shader, TConstArrayView<FRHIShaderParameterUnbind> InUnbinds) final override;
|
|
virtual void RHISetShaderUnbinds(FRHIGraphicsShader* Shader, TConstArrayView<FRHIShaderParameterUnbind> InUnbinds) final override;
|
|
virtual void RHISetDepthStencilState(FRHIDepthStencilState* NewState, uint32 StencilRef) final override;
|
|
virtual void RHISetStencilRef(uint32 StencilRef) final override;
|
|
virtual void RHISetBlendState(FRHIBlendState* NewState, const FLinearColor& BlendFactor) final override;
|
|
virtual void RHISetBlendFactor(const FLinearColor& BlendFactor) final override
|
|
{
|
|
// Currently ignored as well as on RHISetBlendState()...
|
|
}
|
|
|
|
void SetRenderTargets(uint32 NumSimultaneousRenderTargets, const FRHIRenderTargetView* NewRenderTargets, const FRHIDepthRenderTargetView* NewDepthStencilTarget);
|
|
void SetRenderTargetsAndClear(const FRHISetRenderTargetsInfo& RenderTargetsInfo);
|
|
|
|
virtual void RHIDrawPrimitive(uint32 BaseVertexIndex, uint32 NumPrimitives, uint32 NumInstances) final override;
|
|
virtual void RHIDrawPrimitiveIndirect(FRHIBuffer* ArgumentBuffer, uint32 ArgumentOffset) final override;
|
|
virtual void RHIDrawIndexedIndirect(FRHIBuffer* IndexBufferRHI, FRHIBuffer* ArgumentsBufferRHI, int32 DrawArgumentsIndex, uint32 NumInstances) final override;
|
|
virtual void RHIDrawIndexedPrimitive(FRHIBuffer* IndexBuffer, int32 BaseVertexIndex, uint32 FirstInstance, uint32 NumVertices, uint32 StartIndex, uint32 NumPrimitives, uint32 NumInstances) final override;
|
|
virtual void RHIDrawIndexedPrimitiveIndirect(FRHIBuffer* IndexBuffer, FRHIBuffer* ArgumentBuffer, uint32 ArgumentOffset) final override;
|
|
virtual void RHIEnableDepthBoundsTest(bool bEnable) final override;
|
|
virtual void RHISetDepthBounds(float MinDepth, float MaxDepth) final override;
|
|
#if WITH_RHI_BREADCRUMBS
|
|
virtual void RHIBeginBreadcrumbGPU(FRHIBreadcrumbNode* Breadcrumb) final override;
|
|
virtual void RHIEndBreadcrumbGPU (FRHIBreadcrumbNode* Breadcrumb) final override;
|
|
#endif
|
|
virtual void RHIDiscardRenderTargets(bool Depth,bool Stencil,uint32 ColorBitMask) final override;
|
|
|
|
// FIXME: Broken on Android for cubemaps
|
|
virtual void RHICopyTexture(FRHITexture* SourceTexture, FRHITexture* DestTexture, const FRHICopyTextureInfo& CopyInfo) final override;
|
|
|
|
virtual void RHICopyBufferRegion(FRHIBuffer* DestBuffer, uint64 DstOffset, FRHIBuffer* SourceBuffer, uint64 SrcOffset, uint64 NumBytes) final override;
|
|
|
|
// Inline copy
|
|
virtual void RHICopyToStagingBuffer(FRHIBuffer* SourceBufferRHI, FRHIStagingBuffer* DestinationStagingBufferRHI, uint32 InOffset, uint32 InNumBytes) final override;
|
|
virtual void RHIWriteGPUFence_TopOfPipe(FRHICommandListBase& RHICmdList, FRHIGPUFence* FenceRHI) final override;
|
|
virtual void RHIWriteGPUFence(FRHIGPUFence* FenceRHI) final override;
|
|
virtual void* RHILockStagingBuffer(FRHIStagingBuffer* StagingBuffer, FRHIGPUFence* Fence, uint32 Offset, uint32 SizeRHI) final override;
|
|
virtual void RHIUnlockStagingBuffer(FRHIStagingBuffer* StagingBuffer) final override;
|
|
virtual void* LockStagingBuffer_RenderThread(class FRHICommandListImmediate& RHICmdList, FRHIStagingBuffer* StagingBuffer, FRHIGPUFence* Fence, uint32 Offset, uint32 SizeRHI) final override;
|
|
virtual void UnlockStagingBuffer_RenderThread(class FRHICommandListImmediate& RHICmdList, FRHIStagingBuffer* StagingBuffer) final override;
|
|
virtual void RHIMapStagingSurface_RenderThread(class FRHICommandListImmediate& RHICmdList, FRHITexture* Texture, uint32 GPUIndex, FRHIGPUFence* Fence, void*& OutData, int32& OutWidth, int32& OutHeight) final override;
|
|
virtual void RHIUnmapStagingSurface_RenderThread(class FRHICommandListImmediate& RHICmdList, FRHITexture* Texture, uint32 GPUIndex) final override;
|
|
|
|
virtual FStagingBufferRHIRef RHICreateStagingBuffer() final override;
|
|
virtual FGPUFenceRHIRef RHICreateGPUFence(const FName &Name) final override;
|
|
|
|
virtual uint64 RHIGetMinimumAlignmentForBufferBackedSRV(EPixelFormat Format) final override;
|
|
|
|
// Compute the hash of the state components of the PSO initializer for PSO Precaching (only hash data relevant for the RHI specific PSO)
|
|
virtual uint64 RHIComputeStatePrecachePSOHash(const FGraphicsPipelineStateInitializer& Initializer) final override;
|
|
|
|
// Compute the hash of the PSO initializer for PSO Precaching (only hash data relevant for the RHI specific PSO)
|
|
virtual uint64 RHIComputePrecachePSOHash(const FGraphicsPipelineStateInitializer& Initializer) final override;
|
|
|
|
// Check if PSO Initializers are the same used during PSO Precaching (only compare data relevant for the RHI specific PSO)
|
|
virtual bool RHIMatchPrecachePSOInitializers(const FGraphicsPipelineStateInitializer& LHS, const FGraphicsPipelineStateInitializer& RHS) final override;
|
|
|
|
void Cleanup();
|
|
|
|
void PurgeFramebufferFromCaches(GLuint Framebuffer);
|
|
void OnBufferDeletion(GLenum Type, GLuint BufferResource);
|
|
void OnProgramDeletion(GLint ProgramResource);
|
|
void InvalidateTextureResourceInCache(GLuint Resource);
|
|
void InvalidateUAVResourceInCache(GLuint Resource);
|
|
|
|
/** Set a resource on texture target of a specific real OpenGL stage. Goes through cache to eliminate redundant calls. */
|
|
FORCEINLINE void CachedSetupTextureStage(GLint TextureIndex, GLenum Target, GLuint Resource, GLint BaseMip, GLint NumMips)
|
|
{
|
|
FTextureStage& TextureState = ContextState.Textures[TextureIndex];
|
|
const bool bSameTarget = (TextureState.Target == Target);
|
|
const bool bSameResource = (TextureState.Resource == Resource);
|
|
|
|
if (bSameTarget && bSameResource)
|
|
{
|
|
// Nothing changed, no need to update
|
|
return;
|
|
}
|
|
|
|
CachedSetupTextureStageInner(TextureIndex, Target, Resource, BaseMip, NumMips);
|
|
}
|
|
|
|
void CachedSetupTextureStageInner(GLint TextureIndex, GLenum Target, GLuint Resource, GLint BaseMip, GLint NumMips);
|
|
void CachedSetupUAVStage(GLint UAVIndex, GLenum Format, GLuint Resource, bool bLayered, GLint Layer, GLenum Access, GLint Level);
|
|
void UpdateSRV(FOpenGLShaderResourceView* SRV);
|
|
|
|
void CachedBindUniformBuffer(GLuint Buffer)
|
|
{
|
|
check(FOpenGL::SupportsUniformBuffers());
|
|
|
|
VERIFY_GL_SCOPE();
|
|
if (ContextState.UniformBufferBound != Buffer)
|
|
{
|
|
glBindBuffer(GL_UNIFORM_BUFFER, Buffer);
|
|
ContextState.UniformBufferBound = Buffer;
|
|
}
|
|
}
|
|
|
|
void CachedBindBuffer(GLenum Type, GLuint Buffer)
|
|
{
|
|
VERIFY_GL_SCOPE();
|
|
switch (Type)
|
|
{
|
|
case GL_ARRAY_BUFFER:
|
|
if (ContextState.ArrayBufferBound != Buffer)
|
|
{
|
|
glBindBuffer(GL_ARRAY_BUFFER, Buffer);
|
|
ContextState.ArrayBufferBound = Buffer;
|
|
}
|
|
break;
|
|
|
|
case GL_ELEMENT_ARRAY_BUFFER:
|
|
if (ContextState.ElementArrayBufferBound != Buffer)
|
|
{
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Buffer);
|
|
ContextState.ElementArrayBufferBound = Buffer;
|
|
}
|
|
break;
|
|
|
|
case GL_SHADER_STORAGE_BUFFER:
|
|
if (ContextState.StorageBufferBound != Buffer)
|
|
{
|
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, Buffer);
|
|
ContextState.StorageBufferBound = Buffer;
|
|
}
|
|
break;
|
|
|
|
case GL_PIXEL_UNPACK_BUFFER:
|
|
if (ContextState.PixelUnpackBufferBound != Buffer)
|
|
{
|
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, Buffer);
|
|
ContextState.PixelUnpackBufferBound = Buffer;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
checkNoEntry();
|
|
break;
|
|
}
|
|
}
|
|
|
|
FOpenGLSamplerState* GetPointSamplerState() const { return (FOpenGLSamplerState*)PointSamplerState.GetReference(); }
|
|
|
|
void InitializeGLTexture(FOpenGLTexture* Texture, const void* BulkDataPtr, uint64 BulkDataSize);
|
|
|
|
void SetCustomPresent(class FRHICustomPresent* InCustomPresent);
|
|
|
|
#define RHITHREAD_GLTRACE 1
|
|
#if RHITHREAD_GLTRACE
|
|
#define RHITHREAD_GLTRACE_BLOCKING QUICK_SCOPE_CYCLE_COUNTER(STAT_OGLRHIThread_Flush);
|
|
//#define RHITHREAD_GLTRACE_BLOCKING FPlatformMisc::LowLevelOutputDebugStringf(TEXT("FLUSHING %s!\n"), ANSI_TO_TCHAR(__FUNCTION__))
|
|
//#define RHITHREAD_GLTRACE_BLOCKING UE_LOG(LogRHI, Warning,TEXT("FLUSHING %s!\n"), ANSI_TO_TCHAR(__FUNCTION__));
|
|
#else
|
|
#define RHITHREAD_GLTRACE_BLOCKING
|
|
#endif
|
|
|
|
struct FTextureLockTracker
|
|
{
|
|
struct FLockParams
|
|
{
|
|
void* RHIBuffer;
|
|
void* Buffer;
|
|
uint32 MipIndex;
|
|
uint32 ArrayIndex;
|
|
uint32 BufferSize;
|
|
uint32 Stride;
|
|
EResourceLockMode LockMode;
|
|
|
|
FORCEINLINE_DEBUGGABLE FLockParams(void* InRHIBuffer, void* InBuffer, uint32 InArrayIndex, uint32 InMipIndex, uint32 InStride, uint32 InBufferSize, EResourceLockMode InLockMode)
|
|
: RHIBuffer(InRHIBuffer)
|
|
, Buffer(InBuffer)
|
|
, MipIndex(InMipIndex)
|
|
, ArrayIndex(InArrayIndex)
|
|
, BufferSize(InBufferSize)
|
|
, Stride(InStride)
|
|
, LockMode(InLockMode)
|
|
{
|
|
}
|
|
};
|
|
TArray<FLockParams, TInlineAllocator<16> > OutstandingLocks;
|
|
|
|
FTextureLockTracker()
|
|
{}
|
|
|
|
FORCEINLINE_DEBUGGABLE void Lock(void* RHIBuffer, void* Buffer, uint32 ArrayIndex, uint32 MipIndex, uint32 Stride, uint32 SizeRHI, EResourceLockMode LockMode)
|
|
{
|
|
//#if DO_CHECK
|
|
for (auto& Parms : OutstandingLocks)
|
|
{
|
|
check(Parms.RHIBuffer != RHIBuffer || Parms.MipIndex != MipIndex || Parms.ArrayIndex != ArrayIndex);
|
|
}
|
|
//#endif
|
|
OutstandingLocks.Add(FLockParams(RHIBuffer, Buffer, ArrayIndex, MipIndex, Stride, SizeRHI, LockMode));
|
|
}
|
|
|
|
FORCEINLINE_DEBUGGABLE FLockParams Unlock(void* RHIBuffer, uint32 ArrayIndex, uint32 MipIndex)
|
|
{
|
|
for (int32 Index = 0; Index < OutstandingLocks.Num(); Index++)
|
|
{
|
|
FLockParams& CurrentLock = OutstandingLocks[Index];
|
|
if (CurrentLock.RHIBuffer == RHIBuffer && CurrentLock.MipIndex == MipIndex && CurrentLock.ArrayIndex == ArrayIndex)
|
|
{
|
|
FLockParams Result = OutstandingLocks[Index];
|
|
OutstandingLocks.RemoveAtSwap(Index, EAllowShrinking::No);
|
|
return Result;
|
|
}
|
|
}
|
|
check(!"Mismatched RHI buffer locks.");
|
|
return FLockParams(nullptr, nullptr, 0, 0, 0, 0, RLM_WriteOnly);
|
|
}
|
|
};
|
|
|
|
virtual FTextureRHIRef AsyncReallocateTexture2D_RenderThread(class FRHICommandListImmediate& RHICmdList, FRHITexture* Texture2D, int32 NewMipCount, int32 NewSizeX, int32 NewSizeY, FThreadSafeCounter* RequestStatus) final override;
|
|
|
|
virtual FSamplerStateRHIRef RHICreateSamplerState(const FSamplerStateInitializerRHI& Initializer) final override;
|
|
|
|
virtual FGraphicsPipelineStateRHIRef RHICreateGraphicsPipelineState(const FGraphicsPipelineStateInitializer& Initializer) override
|
|
{
|
|
PrepareGFXBoundShaderState(Initializer);
|
|
|
|
return new FRHIGraphicsPipelineStateFallBack(Initializer);
|
|
}
|
|
|
|
virtual void RHISetGraphicsPipelineState(FRHIGraphicsPipelineState* GraphicsState, uint32 StencilRef, bool bApplyAdditionalState) final override;
|
|
|
|
virtual FBoundShaderStateRHIRef RHICreateBoundShaderState(
|
|
FRHIVertexDeclaration* VertexDeclarationRHI,
|
|
FRHIVertexShader* VertexShaderRHI,
|
|
FRHIPixelShader* PixelShaderRHI,
|
|
FRHIGeometryShader* GeometryShaderRHI
|
|
) final override
|
|
{
|
|
checkNoEntry();
|
|
return nullptr;
|
|
}
|
|
|
|
void LinkComputeProgram(FRHIComputeShader* ComputeShaderRHI);
|
|
|
|
|
|
virtual void RHIPostExternalCommandsReset() final override;
|
|
|
|
GLuint GetOpenGLFramebuffer(uint32 NumSimultaneousRenderTargets, FOpenGLTexture** RenderTargets, const uint32* ArrayIndices, const uint32* MipmapLevels, FOpenGLTexture* DepthStencilTarget);
|
|
GLuint GetOpenGLFramebuffer(uint32 NumSimultaneousRenderTargets, FOpenGLTexture** RenderTargets, const uint32* ArrayIndices, const uint32* MipmapLevels, FOpenGLTexture* DepthStencilTarget, FExclusiveDepthStencil DepthStencilAccess, int32 NumRenderingSamples);
|
|
|
|
void ResolveTexture(FOpenGLTexture* Texture, uint32 MipIndex, uint32 ArrayIndex);
|
|
|
|
private:
|
|
FBoundShaderStateRHIRef RHICreateBoundShaderState_Internal(FRHIVertexDeclaration* VertexDeclaration, FRHIVertexShader* VertexShader, FRHIPixelShader* PixelShader, FRHIGeometryShader* GeometryShader, bool FromPSOFileCache);
|
|
|
|
void PrepareGFXBoundShaderState(const FGraphicsPipelineStateInitializer& Initializer);
|
|
|
|
/** called once per frame, used for resource processing */
|
|
void EndFrameTick();
|
|
|
|
/** RHI device state, independent of underlying OpenGL context used */
|
|
FOpenGLRHIState PendingState;
|
|
FSamplerStateRHIRef PointSamplerState;
|
|
|
|
/** A list of all viewport RHIs that have been created. */
|
|
TArray<FOpenGLViewport*> Viewports;
|
|
TRefCountPtr<FOpenGLViewport> DrawingViewport;
|
|
bool bRevertToSharedContextAfterDrawingViewport = false;
|
|
|
|
EPrimitiveType PrimitiveType = PT_Num;
|
|
|
|
/** A history of the most recently used bound shader states, used to keep transient bound shader states from being recreated for each use. */
|
|
TGlobalResource< TBoundShaderStateHistory<10000> > BoundShaderStateHistory;
|
|
|
|
FOpenGLContextState ContextState;
|
|
|
|
template <typename TRHIShader>
|
|
void ApplyStaticUniformBuffers(TRHIShader* Shader);
|
|
|
|
TArray<FRHIUniformBuffer*> GlobalUniformBuffers;
|
|
|
|
/** Cached mip-limits for textures when ARB_texture_view is unavailable */
|
|
TMap<GLuint, TPair<GLenum, GLenum>> TextureMipLimits;
|
|
|
|
/** Underlying platform-specific data */
|
|
struct FPlatformOpenGLDevice* PlatformDevice = nullptr;
|
|
|
|
#if RHI_NEW_GPU_PROFILER
|
|
|
|
friend class FOpenGLRenderQuery;
|
|
|
|
FOpenGLProfiler Profiler;
|
|
|
|
void FlushProfilerStats()
|
|
{
|
|
// Flush accumulated draw stats
|
|
if (Profiler.bEnabled && StatEvent)
|
|
{
|
|
Profiler.EmplaceEvent<UE::RHI::GPUProfiler::FEvent::FStats>() = StatEvent;
|
|
StatEvent = {};
|
|
}
|
|
}
|
|
|
|
#else
|
|
|
|
TOptional<FOpenGLGPUProfiler> GPUProfilingData;
|
|
friend FOpenGLGPUProfiler;
|
|
|
|
void RegisterGPUWork(uint32 NumPrimitives = 0, uint32 NumVertices = 0)
|
|
{
|
|
GPUProfilingData->RegisterGPUWork(NumPrimitives, NumVertices);
|
|
}
|
|
void RegisterGPUDispatch(FIntVector GroupCount)
|
|
{
|
|
GPUProfilingData->RegisterGPUDispatch(GroupCount);
|
|
}
|
|
|
|
#endif
|
|
|
|
FCriticalSection CustomPresentSection;
|
|
TRefCountPtr<class FRHICustomPresent> CustomPresent;
|
|
|
|
void InitializeStateResources();
|
|
|
|
void SetupVertexArrays(uint32 BaseVertexIndex, FOpenGLStream* Streams, uint32 NumStreams, uint32 MaxVertices);
|
|
|
|
void SetupDraw(FOpenGLBuffer* IndexBuffer, uint32 BaseVertexIndex, uint32 MaxVertices);
|
|
void SetupDispatch();
|
|
|
|
/** needs to be called before each draw call */
|
|
void BindPendingFramebuffer();
|
|
void BindPendingShaderState();
|
|
void BindPendingComputeShaderState(FOpenGLComputeShader* ComputeShader);
|
|
void UpdateRasterizerStateInOpenGLContext();
|
|
void UpdateDepthStencilStateInOpenGLContext();
|
|
void UpdateScissorRectInOpenGLContext();
|
|
void UpdateViewportInOpenGLContext();
|
|
|
|
template <class ShaderType> void SetResourcesFromTables(ShaderType* Shader);
|
|
FORCEINLINE void CommitGraphicsResourceTables()
|
|
{
|
|
if (PendingState.bAnyDirtyGraphicsUniformBuffers)
|
|
{
|
|
CommitGraphicsResourceTablesInner();
|
|
}
|
|
}
|
|
void CommitGraphicsResourceTablesInner();
|
|
void CommitComputeResourceTables(FOpenGLComputeShader* ComputeShader);
|
|
void CommitNonComputeShaderConstants();
|
|
void CommitComputeShaderConstants(FOpenGLComputeShader* ComputeShader);
|
|
void SetPendingBlendStateForActiveRenderTargets();
|
|
|
|
template <typename StateType>
|
|
void SetupTexturesForDraw(const StateType& ShaderState, int32 MaxTexturesNeeded);
|
|
void SetupTexturesForDraw();
|
|
|
|
void SetupUAVsForDraw();
|
|
void SetupUAVsForCompute(const FOpenGLComputeShader* ComputeShader);
|
|
void SetupUAVsForProgram(const TBitArray<>& NeededBits, int32 MaxUAVUnitUsed);
|
|
|
|
void RHIClearMRT(const bool* bClearColorArray, int32 NumClearColors, const FLinearColor* ColorArray, bool bClearDepth, float Depth, bool bClearStencil, uint32 Stencil);
|
|
|
|
public:
|
|
/** Remember what RHI user wants set on a specific OpenGL texture stage, translating from Stage and TextureIndex for stage pair. */
|
|
void InternalSetShaderTexture(FOpenGLTexture* Texture, FOpenGLShaderResourceView* SRV, GLint TextureIndex, GLenum Target, GLuint Resource, int NumMips, int LimitMip);
|
|
void InternalSetShaderImageUAV(GLint UAVIndex, GLenum Format, GLuint Resource, bool bLayered, GLint Layer, GLenum Access, GLint Level);
|
|
void InternalSetShaderBufferUAV(GLint UAVIndex, GLuint Resource);
|
|
void InternalSetSamplerStates(GLint TextureIndex, FOpenGLSamplerState* SamplerState);
|
|
void InitializeGLTextureInternal(FOpenGLTexture* Texture, void const* BulkDataPtr, uint64 BulkDataSize);
|
|
|
|
void ClearCachedAttributeState(int32 PositionAttrib, int32 TexCoordsAttrib);
|
|
|
|
private:
|
|
|
|
void ApplyTextureStage(GLint TextureIndex, const FTextureStage& TextureStage, FOpenGLSamplerState* SamplerState);
|
|
|
|
void ReadSurfaceDataRaw(FRHITexture* TextureRHI, FIntRect Rect, TArray<uint8>& OutData, FReadSurfaceDataFlags InFlags);
|
|
|
|
void BindUniformBufferBase(int32 NumUniformBuffers, FRHIUniformBuffer** BoundUniformBuffers, uint32* DynamicOffsets, uint32 FirstUniformBuffer, bool ForceUpdate);
|
|
|
|
void ClearCurrentFramebufferWithCurrentScissor(int8 ClearType, int32 NumClearColors, const bool* bClearColorArray, const FLinearColor* ClearColorArray, float Depth, uint32 Stencil);
|
|
|
|
FTextureLockTracker GLLockTracker;
|
|
|
|
class FOpenGLFenceKick
|
|
{
|
|
public:
|
|
FOpenGLFenceKick(FOpenGLDynamicRHI* RHI)
|
|
: RHI(*RHI)
|
|
{}
|
|
~FOpenGLFenceKick();
|
|
|
|
void OnDrawCall();
|
|
void Reset();
|
|
|
|
private:
|
|
void InsertKick();
|
|
|
|
TArray<UGLsync> Syncs;
|
|
int32 DrawCounter = 0;
|
|
GLuint LastSeenFramebuffer = 0;
|
|
|
|
FOpenGLDynamicRHI& RHI;
|
|
} KickHint { this };
|
|
};
|
|
|
|
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
|
|
|
/** Implements the OpenGLDrv module as a dynamic RHI providing module. */
|
|
class FOpenGLDynamicRHIModule : public IDynamicRHIModule
|
|
{
|
|
public:
|
|
|
|
// IModuleInterface
|
|
virtual bool SupportsDynamicReloading() override { return false; }
|
|
|
|
// IDynamicRHIModule
|
|
virtual bool IsSupported() override;
|
|
|
|
virtual FDynamicRHI* CreateRHI(ERHIFeatureLevel::Type RequestedFeatureLevel = ERHIFeatureLevel::Num) override;
|
|
};
|
|
|
|
extern ERHIFeatureLevel::Type GRequestedFeatureLevel;
|