OpenGLRenderer: Take advantage of glClipControl if available

This commit is contained in:
SirLynix 2022-09-06 13:01:44 +02:00
parent 6bb1ee283f
commit 131faa4fbd
5 changed files with 71 additions and 4 deletions

View File

@ -52,7 +52,10 @@ namespace Nz::GL
enum class Extension enum class Extension
{ {
ClipControl,
DebugOutput,
DepthClamp, DepthClamp,
PolygonMode,
SpirV, SpirV,
StorageBuffers, StorageBuffers,
TextureCompressionS3tc, TextureCompressionS3tc,
@ -149,6 +152,8 @@ namespace Nz::GL
inline bool IsExtensionSupported(Extension extension) const; inline bool IsExtensionSupported(Extension extension) const;
inline bool IsExtensionSupported(const std::string& extension) const; inline bool IsExtensionSupported(const std::string& extension) const;
inline bool HasZeroToOneDepth() const;
bool Initialize(const ContextParams& params); bool Initialize(const ContextParams& params);
inline void NotifyBufferDestruction(GLuint buffer) const; inline void NotifyBufferDestruction(GLuint buffer) const;
@ -253,6 +258,7 @@ namespace Nz::GL
mutable State m_state; mutable State m_state;
mutable bool m_didCollectErrors; mutable bool m_didCollectErrors;
mutable bool m_hadAnyError; mutable bool m_hadAnyError;
bool m_hasZeroToOneDepth;
}; };
} }

View File

@ -51,6 +51,11 @@ namespace Nz::GL
return m_supportedExtensions.find(extension) != m_supportedExtensions.end(); return m_supportedExtensions.find(extension) != m_supportedExtensions.end();
} }
inline bool Context::HasZeroToOneDepth() const
{
return m_hasZeroToOneDepth;
}
inline void Context::NotifyBufferDestruction(GLuint buffer) const inline void Context::NotifyBufferDestruction(GLuint buffer) const
{ {
for (GLuint& boundBuffer : m_state.bufferTargets) for (GLuint& boundBuffer : m_state.bufferTargets)

View File

@ -13,7 +13,7 @@
#include <GLES3/gl32.h> #include <GLES3/gl32.h>
#include <GLES2/gl2ext.h> #include <GLES2/gl2ext.h>
// Define some OpenGL (not ES) extensions // Define some OpenGL (not ES) defines/function types
#define GL_POINT 0x1B00 #define GL_POINT 0x1B00
#define GL_LINE 0x1B01 #define GL_LINE 0x1B01
#define GL_FILL 0x1B02 #define GL_FILL 0x1B02
@ -22,8 +22,21 @@
#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F #define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
typedef void (GL_APIENTRYP PFNGLDRAWBUFFERPROC) (GLenum buf); typedef void (GL_APIENTRYP PFNGLDRAWBUFFERPROC) (GLenum buf);
typedef void (GL_APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode); typedef void (GL_APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
// Clip control (OpenGL 4.5)
#define GL_LOWER_LEFT 0x8CA1
#define GL_UPPER_LEFT 0x8CA2
#define GL_NEGATIVE_ONE_TO_ONE 0x935E
#define GL_ZERO_TO_ONE 0x935F
#define GL_CLIP_ORIGIN 0x935C
#define GL_CLIP_DEPTH_MODE 0x935D
typedef void (GL_APIENTRYP PFNGLCLIPCONTROLPROC) (GLenum origin, GLenum depth);
// SPIR-V shaders (OpenGL 4.6)
typedef void (GL_APIENTRYP PFNGLSPECIALIZESHADERPROC) (GLuint shader, const GLchar* pEntryPoint, GLuint numSpecializationConstants, const GLuint* pConstantIndex, const GLuint* pConstantValue); typedef void (GL_APIENTRYP PFNGLSPECIALIZESHADERPROC) (GLuint shader, const GLchar* pEntryPoint, GLuint numSpecializationConstants, const GLuint* pConstantIndex, const GLuint* pConstantValue);
/*** Functions ***/
// OpenGL core // OpenGL core
#define NAZARA_OPENGLRENDERER_FOREACH_GLES_FUNC(cb, extCb) \ #define NAZARA_OPENGLRENDERER_FOREACH_GLES_FUNC(cb, extCb) \
cb(glActiveTexture, PFNGLACTIVETEXTUREPROC) \ cb(glActiveTexture, PFNGLACTIVETEXTUREPROC) \
@ -183,6 +196,8 @@ typedef void (GL_APIENTRYP PFNGLSPECIALIZESHADERPROC) (GLuint shader, const GLch
extCb(glObjectLabel, PFNGLOBJECTLABELPROC) \ extCb(glObjectLabel, PFNGLOBJECTLABELPROC) \
extCb(glPopDebugGroup, PFNGLPOPDEBUGGROUPPROC) \ extCb(glPopDebugGroup, PFNGLPOPDEBUGGROUPPROC) \
extCb(glPushDebugGroup, PFNGLPUSHDEBUGGROUPPROC) \ extCb(glPushDebugGroup, PFNGLPUSHDEBUGGROUPPROC) \
/* OpenGL 4.5 - GL_ARB_clip_control/GL_EXT_clip_control */ \
extCb(glClipControl, PFNGLCLIPCONTROLPROC) \
/* OpenGL 4.6 - GL_ARB_spirv_extensions */\ /* OpenGL 4.6 - GL_ARB_spirv_extensions */\
extCb(glSpecializeShader, PFNGLSPECIALIZESHADERPROC) \ extCb(glSpecializeShader, PFNGLSPECIALIZESHADERPROC) \

View File

@ -96,8 +96,11 @@ namespace Nz
{ {
return context.IsExtensionSupported(std::string(ext)); return context.IsExtensionSupported(std::string(ext));
}; };
env.flipYPosition = true; env.flipYPosition = true;
env.remapZPosition = true;
if (!context.HasZeroToOneDepth())
env.remapZPosition = true;
nzsl::GlslWriter writer; nzsl::GlslWriter writer;
writer.SetEnv(env); writer.SetEnv(env);

View File

@ -109,7 +109,8 @@ namespace Nz::GL
m_vaoCache(*this), m_vaoCache(*this),
m_device(device), m_device(device),
m_didCollectErrors(false), m_didCollectErrors(false),
m_hadAnyError(false) m_hadAnyError(false),
m_hasZeroToOneDepth(false)
{ {
} }
@ -381,6 +382,22 @@ namespace Nz::GL
m_extensionStatus.fill(ExtensionStatus::NotSupported); m_extensionStatus.fill(ExtensionStatus::NotSupported);
// Clip control
if (m_params.type == ContextType::OpenGL && glVersion >= 450)
m_extensionStatus[UnderlyingCast(Extension::ClipControl)] = ExtensionStatus::Core;
else if (m_supportedExtensions.count("GL_ARB_clip_control"))
m_extensionStatus[UnderlyingCast(Extension::ClipControl)] = ExtensionStatus::ARB;
else if (m_supportedExtensions.count("GL_EXT_clip_control"))
m_extensionStatus[UnderlyingCast(Extension::ClipControl)] = ExtensionStatus::EXT;
// Debug output
if ((m_params.type == ContextType::OpenGL && glVersion >= 430) || (m_params.type == ContextType::OpenGL_ES && glVersion >= 320))
m_extensionStatus[UnderlyingCast(Extension::DebugOutput)] = ExtensionStatus::Core;
else if (m_supportedExtensions.count("GL_KHR_debug"))
m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::KHR;
else if (m_supportedExtensions.count("GL_ARB_debug_output"))
m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::ARB;
// Depth clamp // Depth clamp
if (m_params.type == ContextType::OpenGL && glVersion >= 320) if (m_params.type == ContextType::OpenGL && glVersion >= 320)
m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::Core; m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::Core;
@ -391,6 +408,12 @@ namespace Nz::GL
else if (m_supportedExtensions.count("GL_NV_depth_clamp")) else if (m_supportedExtensions.count("GL_NV_depth_clamp"))
m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::Vendor; m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::Vendor;
// Polygon mode
if (m_params.type == ContextType::OpenGL)
m_extensionStatus[UnderlyingCast(Extension::PolygonMode)] = ExtensionStatus::Core;
else if (m_supportedExtensions.count("GL_NV_polygon_mode"))
m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::Vendor;
// SPIR-V support // SPIR-V support
if (m_params.type == ContextType::OpenGL && glVersion >= 460) if (m_params.type == ContextType::OpenGL && glVersion >= 460)
m_extensionStatus[UnderlyingCast(Extension::SpirV)] = ExtensionStatus::Core; m_extensionStatus[UnderlyingCast(Extension::SpirV)] = ExtensionStatus::Core;
@ -421,6 +444,14 @@ namespace Nz::GL
#undef NAZARA_OPENGLRENDERER_EXT_FUNC #undef NAZARA_OPENGLRENDERER_EXT_FUNC
#undef NAZARA_OPENGLRENDERER_FUNC #undef NAZARA_OPENGLRENDERER_FUNC
// Match Vulkan convention if supported (so we don't have to inject code in the shader to fix it)
if (glClipControl)
{
// TODO: Using GL_UPPER_LEFT causes some issues I still have to figure out
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
m_hasZeroToOneDepth = true;
}
// Always enable cubemap sampling (as it's the guaranteed behavior on Vulkan and OpenGL ES 3.0) // Always enable cubemap sampling (as it's the guaranteed behavior on Vulkan and OpenGL ES 3.0)
if (m_params.type == ContextType::OpenGL && (glVersion >= 320 || m_supportedExtensions.count("GL_ARB_seamless_cube_map"))) if (m_params.type == ContextType::OpenGL && (glVersion >= 320 || m_supportedExtensions.count("GL_ARB_seamless_cube_map")))
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
@ -847,7 +878,14 @@ namespace Nz::GL
{ {
SymbolLoader loader(*this); SymbolLoader loader(*this);
if (function == "glDebugMessageCallback") if (function == "glClipControl")
{
constexpr std::size_t functionIndex = UnderlyingCast(FunctionIndex::glClipControl);
return loader.Load<PFNGLCLIPCONTROLEXTPROC, functionIndex>(glClipControl, "glClipControlEXT", false); //< from GL_EXT_clip_control
}
else if (function == "glDebugMessageCallback")
{ {
constexpr std::size_t functionIndex = UnderlyingCast(FunctionIndex::glDebugMessageCallback); constexpr std::size_t functionIndex = UnderlyingCast(FunctionIndex::glDebugMessageCallback);