From d31dbb1bc12505d503cb97b57518a3e48cb2da11 Mon Sep 17 00:00:00 2001
From: Kelebek1 <eeeedddccc@hotmail.co.uk>
Date: Wed, 24 Feb 2021 22:04:51 +0000
Subject: [PATCH] Implement glDepthRangeIndexeddNV

---
 externals/glad/include/glad/glad.h               | 3 +++
 externals/glad/src/glad.c                        | 2 ++
 src/video_core/renderer_opengl/gl_device.cpp     | 2 ++
 src/video_core/renderer_opengl/gl_device.h       | 5 +++++
 src/video_core/renderer_opengl/gl_rasterizer.cpp | 6 +++++-
 5 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/externals/glad/include/glad/glad.h b/externals/glad/include/glad/glad.h
index 6e16358ea5..191bb9fcb8 100644
--- a/externals/glad/include/glad/glad.h
+++ b/externals/glad/include/glad/glad.h
@@ -5156,6 +5156,9 @@ GLAPI PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv;
 typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC)(GLuint index, GLdouble n, GLdouble f);
 GLAPI PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed;
 #define glDepthRangeIndexed glad_glDepthRangeIndexed
+typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDDNVPROC)(GLuint index, GLdouble n, GLdouble f);
+GLAPI PFNGLDEPTHRANGEINDEXEDDNVPROC glad_glDepthRangeIndexeddNV;
+#define glDepthRangeIndexeddNV glad_glDepthRangeIndexeddNV
 typedef void (APIENTRYP PFNGLGETFLOATI_VPROC)(GLenum target, GLuint index, GLfloat *data);
 GLAPI PFNGLGETFLOATI_VPROC glad_glGetFloati_v;
 #define glGetFloati_v glad_glGetFloati_v
diff --git a/externals/glad/src/glad.c b/externals/glad/src/glad.c
index d3e13163f6..7b24cd68df 100644
--- a/externals/glad/src/glad.c
+++ b/externals/glad/src/glad.c
@@ -1044,6 +1044,7 @@ PFNGLDEPTHMASKPROC glad_glDepthMask = NULL;
 PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL;
 PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv = NULL;
 PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL;
+PFNGLDEPTHRANGEINDEXEDDNVPROC glad_glDepthRangeIndexeddNV = NULL;
 PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL;
 PFNGLDETACHSHADERPROC glad_glDetachShader = NULL;
 PFNGLDISABLEPROC glad_glDisable = NULL;
@@ -7971,6 +7972,7 @@ static void load_GL_NV_depth_buffer_float(GLADloadproc load) {
 	glad_glDepthRangedNV = (PFNGLDEPTHRANGEDNVPROC)load("glDepthRangedNV");
 	glad_glClearDepthdNV = (PFNGLCLEARDEPTHDNVPROC)load("glClearDepthdNV");
 	glad_glDepthBoundsdNV = (PFNGLDEPTHBOUNDSDNVPROC)load("glDepthBoundsdNV");
+	glad_glDepthRangeIndexeddNV = (PFNGLDEPTHRANGEINDEXEDDNVPROC)load("glDepthRangeIndexeddNV");
 }
 static void load_GL_NV_draw_texture(GLADloadproc load) {
 	if(!GLAD_GL_NV_draw_texture) return;
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index 48d5c4a5e6..1ae5f1d624 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -239,6 +239,7 @@ Device::Device() {
     has_nv_viewport_array2 = GLAD_GL_NV_viewport_array2;
     has_vertex_buffer_unified_memory = GLAD_GL_NV_vertex_buffer_unified_memory;
     has_debugging_tool_attached = IsDebugToolAttached(extensions);
+    has_depth_buffer_float = HasExtension(extensions, "GL_NV_depth_buffer_float");
 
     // At the moment of writing this, only Nvidia's driver optimizes BufferSubData on exclusive
     // uniform buffers as "push constants"
@@ -275,6 +276,7 @@ Device::Device(std::nullptr_t) {
     has_image_load_formatted = true;
     has_texture_shadow_lod = true;
     has_variable_aoffi = true;
+    has_depth_buffer_float = true;
 }
 
 bool Device::TestVariableAoffi() {
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h
index ee053776d3..f24bd0c7b7 100644
--- a/src/video_core/renderer_opengl/gl_device.h
+++ b/src/video_core/renderer_opengl/gl_device.h
@@ -122,6 +122,10 @@ public:
         return use_driver_cache;
     }
 
+    bool HasDepthBufferFloat() const {
+        return has_depth_buffer_float;
+    }
+
 private:
     static bool TestVariableAoffi();
     static bool TestPreciseBug();
@@ -150,6 +154,7 @@ private:
     bool use_assembly_shaders{};
     bool use_asynchronous_shaders{};
     bool use_driver_cache{};
+    bool has_depth_buffer_float{};
 };
 
 } // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 418644108b..4610fd1604 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -889,7 +889,11 @@ void RasterizerOpenGL::SyncViewport() {
             const GLdouble reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne;
             const GLdouble near_depth = src.translate_z - src.scale_z * reduce_z;
             const GLdouble far_depth = src.translate_z + src.scale_z;
-            glDepthRangeIndexed(static_cast<GLuint>(i), near_depth, far_depth);
+            if (device.HasDepthBufferFloat()) {
+                glDepthRangeIndexeddNV(static_cast<GLuint>(i), near_depth, far_depth);
+            } else {
+                glDepthRangeIndexed(static_cast<GLuint>(i), near_depth, far_depth);
+            }
 
             if (!GLAD_GL_NV_viewport_swizzle) {
                 continue;