143 lines
5.3 KiB
C++
143 lines
5.3 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
OpenGLUtil.h: OpenGL RHI utility definitions.
|
|
=============================================================================*/
|
|
|
|
#pragma once
|
|
|
|
#include "RHICommandList.h"
|
|
#include "OpenGLThirdParty.h"
|
|
#include "OpenGLShaderResources.h"
|
|
|
|
class FOpenGLTexture;
|
|
|
|
/** Set to 1 to enable the VERIFY_GL macros which call glGetError */
|
|
#define ENABLE_VERIFY_GL (0 & DO_CHECK)
|
|
#define ENABLE_VERIFY_GL_TRACE 0
|
|
|
|
// Include GL debug output functionality on everything but shipping configs.
|
|
// to enable the debug output specify '-OpenGLDebugLevel=[1-5]' via the command line.
|
|
#define ENABLE_DEBUG_OUTPUT (!UE_BUILD_SHIPPING)
|
|
#if !ENABLE_DEBUG_OUTPUT
|
|
inline bool IsOGLDebugOutputEnabled() { return false; }
|
|
inline int32 GetOGLDebugOutputLevel() { return 0; }
|
|
#else
|
|
bool IsOGLDebugOutputEnabled();
|
|
int32 GetOGLDebugOutputLevel();
|
|
#endif
|
|
|
|
// Additional check that our GL calls are occurring on the expected thread
|
|
#define ENABLE_VERIFY_GL_THREAD (!(UE_BUILD_TEST || UE_BUILD_SHIPPING))
|
|
|
|
/** Set to 1 to verify that the the engine side uniform buffer layout matches the driver side of the GLSL shader*/
|
|
#define ENABLE_UNIFORM_BUFFER_LAYOUT_VERIFICATION ( 0 & UE_BUILD_DEBUG & (!PLATFORM_ANDROID))
|
|
|
|
/** Set to 1 to additinally dump uniform buffer layout at shader link time, this assumes ENABLE_UNIFORM_BUFFER_LAYOUT_VERIFICATION == 1 */
|
|
#define ENABLE_UNIFORM_BUFFER_LAYOUT_DUMP 0
|
|
|
|
/** Set to 1 to enable calls to place event markers into the OpenGL stream
|
|
this is purposefully not considered for OPENGL_PERFORMANCE_DATA_INVALID,
|
|
since there is an additional cvar OpenGLConsoleVariables::bEnableARBDebug*/
|
|
|
|
#define ENABLE_OPENGL_DEBUG_GROUPS 1
|
|
|
|
#define OPENGL_PERFORMANCE_DATA_INVALID (ENABLE_VERIFY_GL | ENABLE_UNIFORM_BUFFER_LAYOUT_VERIFICATION | DEBUG_GL_SHADERS)
|
|
|
|
void SetOpenGLResourceName(FOpenGLTexture* Texture, const ANSICHAR* Name);
|
|
void SetOpenGLResourceName(FOpenGLTexture* Texture, const TCHAR* Name);
|
|
|
|
/**
|
|
* Convert from ECubeFace to GLenum type
|
|
* @param Face - ECubeFace type to convert
|
|
* @return OpenGL cube face enum value
|
|
*/
|
|
GLenum GetOpenGLCubeFace(ECubeFace Face);
|
|
|
|
extern bool PlatformOpenGLThreadHasRenderingContext();
|
|
|
|
#if ENABLE_VERIFY_GL_THREAD
|
|
#define CHECK_EXPECTED_GL_THREAD() \
|
|
if (!PlatformOpenGLThreadHasRenderingContext()) \
|
|
{ \
|
|
UE_LOG(LogRHI, Fatal, TEXT("Potential use of GL context from incorrect thread. [IsInGameThread() = %d, IsInRenderingThread() = %d, IsInRHIThread() = %d, IsRunningRHIInSeparateThread() = %d]"), IsInGameThread(), IsInRenderingThread(), IsInRHIThread(), IsRunningRHIInSeparateThread()); \
|
|
}
|
|
#else
|
|
#define CHECK_EXPECTED_GL_THREAD()
|
|
#endif
|
|
|
|
#if ENABLE_VERIFY_GL
|
|
extern int32 PlatformGlGetError();
|
|
|
|
void VerifyOpenGLResult(GLenum ErrorCode, const TCHAR* Msg1, const TCHAR* Msg2, const TCHAR* Filename, uint32 Line);
|
|
#define VERIFY_GL(msg) { CHECK_EXPECTED_GL_THREAD(); GLenum ErrorCode = PlatformGlGetError(); if (ErrorCode != GL_NO_ERROR) { VerifyOpenGLResult(ErrorCode,TEXT(#msg),TEXT(""),TEXT(__FILE__),__LINE__); } }
|
|
|
|
struct FOpenGLErrorScope
|
|
{
|
|
const char* FunctionName;
|
|
const TCHAR* Filename;
|
|
const uint32 Line;
|
|
|
|
FOpenGLErrorScope(
|
|
const char* InFunctionName,
|
|
const TCHAR* InFilename,
|
|
const uint32 InLine)
|
|
: FunctionName(InFunctionName)
|
|
, Filename(InFilename)
|
|
, Line(InLine)
|
|
{
|
|
#if ENABLE_VERIFY_GL_TRACE
|
|
UE_LOG(LogRHI, Log, TEXT("log before %s(%d): %s"), InFilename, InLine, ANSI_TO_TCHAR(InFunctionName));
|
|
#endif
|
|
CheckForErrors(0);
|
|
}
|
|
|
|
~FOpenGLErrorScope()
|
|
{
|
|
#if ENABLE_VERIFY_GL_TRACE
|
|
UE_LOG(LogRHI, Log, TEXT("log after %s(%d): %s"), Filename, Line, ANSI_TO_TCHAR(FunctionName));
|
|
|
|
#endif
|
|
|
|
CheckForErrors(1);
|
|
}
|
|
|
|
void CheckForErrors(int32 BeforeOrAfter)
|
|
{
|
|
check(PlatformOpenGLThreadHasRenderingContext());
|
|
|
|
GLenum ErrorCode = PlatformGlGetError();
|
|
if (ErrorCode != GL_NO_ERROR)
|
|
{
|
|
const TCHAR* PrefixStrings[] = { TEXT("Before "), TEXT("During ") };
|
|
VerifyOpenGLResult(ErrorCode,PrefixStrings[BeforeOrAfter], ANSI_TO_TCHAR(FunctionName),Filename,Line);
|
|
}
|
|
}
|
|
};
|
|
#define MACRO_TOKENIZER(IdentifierName, Msg, FileName, LineNumber) FOpenGLErrorScope IdentifierName_ ## LineNumber (Msg, FileName, LineNumber)
|
|
#define MACRO_TOKENIZER2(IdentifierName, Msg, FileName, LineNumber) MACRO_TOKENIZER(IdentiferName, Msg, FileName, LineNumber)
|
|
#define VERIFY_GL_SCOPE_WITH_MSG_STR(MsgStr) CHECK_EXPECTED_GL_THREAD(); MACRO_TOKENIZER2(ErrorScope_, MsgStr, TEXT(__FILE__), __LINE__)
|
|
#define VERIFY_GL_SCOPE() VERIFY_GL_SCOPE_WITH_MSG_STR(__FUNCTION__)
|
|
#define VERIFY_GL_FUNC(Func, ...) { VERIFY_GL_SCOPE_WITH_MSG_STR((#Func)); Func(__VA_ARGS__); }
|
|
|
|
/**
|
|
* Some important GL calls are trapped individually.
|
|
*/
|
|
#define glBlitFramebuffer(...) VERIFY_GL_FUNC(glBlitFramebuffer, __VA_ARGS__)
|
|
#define glTexImage2D(...) VERIFY_GL_FUNC(glTexImage2D, __VA_ARGS__)
|
|
#define glTexSubImage2D(...) VERIFY_GL_FUNC(glTexSubImage2D, __VA_ARGS__)
|
|
#define glCompressedTexImage2D(...) VERIFY_GL_FUNC(glCompressedTexImage2D, __VA_ARGS__)
|
|
|
|
#else
|
|
#define VERIFY_GL(...) CHECK_EXPECTED_GL_THREAD()
|
|
#define VERIFY_GL_SCOPE(...) CHECK_EXPECTED_GL_THREAD()
|
|
#endif
|
|
|
|
struct FRHICommandGLCommandString
|
|
{
|
|
static const TCHAR* TStr() { return TEXT("FRHICommandGLCommand"); }
|
|
};
|
|
|
|
#define GL_CAPTURE_CALLSTACK 0 // Capture the callstack at the point of enqueuing the command.
|
|
|