[Mesa-dev] [PATCH v5 1/4] mesa: add support for nvidia conservative rasterization extensions

Rhys Perry pendingchaos02 at gmail.com
Sat Apr 7 22:15:02 UTC 2018


Although the specs are written against compatibility GL 4.3 and allows core
profile and GLES2+, it is exposed for GL 1.0+ and GLES1 and GLES2+.

Signed-off-by: Rhys Perry <pendingchaos02 at gmail.com>
---
 src/mapi/glapi/gen/gl_API.xml           |  47 ++++++++++++
 src/mapi/glapi/gen/gl_genexec.py        |   1 +
 src/mesa/Makefile.sources               |   2 +
 src/mesa/main/attrib.c                  |  60 ++++++++++++---
 src/mesa/main/conservativeraster.c      | 127 ++++++++++++++++++++++++++++++++
 src/mesa/main/conservativeraster.h      |  48 ++++++++++++
 src/mesa/main/context.c                 |  10 +++
 src/mesa/main/dlist.c                   |  86 +++++++++++++++++++++
 src/mesa/main/enable.c                  |  14 ++++
 src/mesa/main/extensions_table.h        |   4 +
 src/mesa/main/get.c                     |   3 +
 src/mesa/main/get_hash_params.py        |  13 ++++
 src/mesa/main/mtypes.h                  |  28 ++++++-
 src/mesa/main/tests/dispatch_sanity.cpp |  27 +++++++
 src/mesa/main/viewport.c                |  57 ++++++++++++++
 src/mesa/main/viewport.h                |   6 ++
 src/mesa/meson.build                    |   2 +
 17 files changed, 524 insertions(+), 11 deletions(-)
 create mode 100644 src/mesa/main/conservativeraster.c
 create mode 100644 src/mesa/main/conservativeraster.h

diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index 38c1921047..db312370b1 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -12871,6 +12871,53 @@
   <enum name="CONSERVATIVE_RASTERIZATION_INTEL" value="0x83FE"/>
 </category>
 
+<category name="GL_NV_conservative_raster" number="465">
+    <enum name="CONSERVATIVE_RASTERIZATION_NV"       value="0x9346">
+        <size name="Get" mode="get"/>
+    </enum>
+    <enum name="SUBPIXEL_PRECISION_BIAS_X_BITS_NV"   value="0x9347">
+        <size name="Get" mode="get"/>
+    </enum>
+    <enum name="SUBPIXEL_PRECISION_BIAS_Y_BITS_NV"   value="0x9348">
+        <size name="Get" mode="get"/>
+    </enum>
+    <enum name="MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV" value="0x9349">
+        <size name="Get" mode="get"/>
+    </enum>
+    <function name="SubpixelPrecisionBiasNV" es1="1.0" es2="2.0" no_error="true">
+        <param name="xbits" type="GLuint"/>
+        <param name="ybits" type="GLuint"/>
+    </function>
+</category>
+
+<category name="GL_NV_conservative_raster_dilate" number="480">
+    <enum name="CONSERVATIVE_RASTER_DILATE_NV"             value="0x9379">
+        <size name="Get" mode="get"/>
+    </enum>
+    <enum name="CONSERVATIVE_RASTER_DILATE_RANGE_NV"       value="0x937A">
+        <size name="Get" mode="get"/>
+    </enum>
+    <enum name="CONSERVATIVE_RASTER_DILATE_GRANULARITY_NV" value="0x937B">
+        <size name="Get" mode="get"/>
+    </enum>
+    <function name="ConservativeRasterParameterfNV" es1="1.0" es2="2.0" no_error="true">
+        <param name="pname" type="GLenum"/>
+        <param name="param" type="GLfloat"/>
+    </function>
+</category>
+
+<category name="GL_NV_conservative_pre_snap_triangles" number="487">
+    <enum name="CONSERVATIVE_RASTER_MODE_NV"       value="0x954D">
+        <size name="Get" mode="get"/>
+    </enum>
+    <enum name="CONSERVATIVE_RASTER_MODE_POST_SNAP_NV"   value="0x954E"/>
+    <enum name="CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV"   value="0x954F"/>
+    <function name="ConservativeRasterParameteriNV" es1="1.0" es2="2.0" no_error="true">
+        <param name="pname" type="GLenum"/>
+        <param name="param" type="GLint"/>
+    </function>
+</category>
+
 <xi:include href="INTEL_performance_query.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
 
 <category name="GL_EXT_polygon_offset_clamp" number="460">
diff --git a/src/mapi/glapi/gen/gl_genexec.py b/src/mapi/glapi/gen/gl_genexec.py
index aaff9f230b..be8013b62b 100644
--- a/src/mapi/glapi/gen/gl_genexec.py
+++ b/src/mapi/glapi/gen/gl_genexec.py
@@ -62,6 +62,7 @@ header = """/**
 #include "main/colortab.h"
 #include "main/compute.h"
 #include "main/condrender.h"
+#include "main/conservativeraster.h"
 #include "main/context.h"
 #include "main/convolve.h"
 #include "main/copyimage.h"
diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources
index 92565ef8f5..952949c737 100644
--- a/src/mesa/Makefile.sources
+++ b/src/mesa/Makefile.sources
@@ -49,6 +49,8 @@ MAIN_FILES = \
 	main/condrender.c \
 	main/condrender.h \
 	main/config.h \
+	main/conservativeraster.c \
+	main/conservativeraster.h \
 	main/context.c \
 	main/context.h \
 	main/convolve.c \
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index 9c632ffb51..50be1fee7e 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -138,6 +138,9 @@ struct gl_enable_attrib
 
    /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
    GLboolean sRGBEnabled;
+
+   /* GL_NV_conservative_raster */
+   GLboolean ConservativeRasterization;
 };
 
 
@@ -178,6 +181,13 @@ struct texture_state
 };
 
 
+struct viewport_state
+{
+   struct gl_viewport_attrib ViewportArray[MAX_VIEWPORTS];
+   GLuint SubpixelPrecisionBias[2];
+};
+
+
 /** An unused GL_*_BIT value */
 #define DUMMY_BIT 0x10000000
 
@@ -394,6 +404,9 @@ _mesa_PushAttrib(GLbitfield mask)
 
       /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
       attr->sRGBEnabled = ctx->Color.sRGBEnabled;
+
+      /* GL_NV_conservative_raster */
+      attr->ConservativeRasterization = ctx->ConservativeRasterization;
    }
 
    if (mask & GL_EVAL_BIT) {
@@ -545,11 +558,23 @@ _mesa_PushAttrib(GLbitfield mask)
    }
 
    if (mask & GL_VIEWPORT_BIT) {
-      if (!push_attrib(ctx, &head, GL_VIEWPORT_BIT,
-                       sizeof(struct gl_viewport_attrib)
-                       * ctx->Const.MaxViewports,
-                       (void*)&ctx->ViewportArray))
+      struct viewport_state *viewstate = CALLOC_STRUCT(viewport_state);
+      if (!viewstate) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_VIEWPORT_BIT)");
+         goto end;
+      }
+
+      if (!save_attrib_data(&head, GL_VIEWPORT_BIT, viewstate)) {
+         free(viewstate);
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_VIEWPORT_BIT)");
          goto end;
+      }
+
+      memcpy(&viewstate->ViewportArray, &ctx->ViewportArray,
+             sizeof(struct gl_viewport_attrib)*ctx->Const.MaxViewports);
+
+      viewstate->SubpixelPrecisionBias[0] = ctx->SubpixelPrecisionBias[0];
+      viewstate->SubpixelPrecisionBias[1] = ctx->SubpixelPrecisionBias[1];
    }
 
    /* GL_ARB_multisample */
@@ -714,6 +739,13 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable)
    TEST_AND_UPDATE(ctx->Color.sRGBEnabled, enable->sRGBEnabled,
                    GL_FRAMEBUFFER_SRGB);
 
+   /* GL_NV_conservative_raster */
+   if (ctx->Extensions.NV_conservative_raster) {
+      TEST_AND_UPDATE(ctx->ConservativeRasterization,
+                      enable->ConservativeRasterization,
+                      GL_CONSERVATIVE_RASTERIZATION_NV);
+   }
+
    /* texture unit enables */
    for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
       const GLbitfield enabled = enable->Texture[i];
@@ -1127,7 +1159,8 @@ _mesa_PopAttrib(void)
                                       ctx->DriverFlags.NewSampleAlphaToXEnable |
                                       ctx->DriverFlags.NewSampleMask |
                                       ctx->DriverFlags.NewScissorTest |
-                                      ctx->DriverFlags.NewStencil;
+                                      ctx->DriverFlags.NewStencil |
+                                      ctx->DriverFlags.NewNvConservativeRasterization;
             }
             break;
          case GL_EVAL_BIT:
@@ -1419,13 +1452,20 @@ _mesa_PopAttrib(void)
          case GL_VIEWPORT_BIT:
             {
                unsigned i;
-               const struct gl_viewport_attrib *vp;
-               vp = (const struct gl_viewport_attrib *) attr->data;
+               const struct viewport_state *viewstate;
+               viewstate = (const struct viewport_state *) attr->data;
 
                for (i = 0; i < ctx->Const.MaxViewports; i++) {
-                  _mesa_set_viewport(ctx, i, vp[i].X, vp[i].Y, vp[i].Width,
-                                     vp[i].Height);
-                  _mesa_set_depth_range(ctx, i, vp[i].Near, vp[i].Far);
+                  const struct gl_viewport_attrib *vp = &viewstate->ViewportArray[i];
+                  _mesa_set_viewport(ctx, i, vp->X, vp->Y, vp->Width,
+                                     vp->Height);
+                  _mesa_set_depth_range(ctx, i, vp->Near, vp->Far);
+               }
+
+               if (ctx->Extensions.NV_conservative_raster) {
+                  GLuint biasx = viewstate->SubpixelPrecisionBias[0];
+                  GLuint biasy = viewstate->SubpixelPrecisionBias[1];
+                  _mesa_SubpixelPrecisionBiasNV(biasx, biasy);
                }
             }
             break;
diff --git a/src/mesa/main/conservativeraster.c b/src/mesa/main/conservativeraster.c
new file mode 100644
index 0000000000..ee9c672fed
--- /dev/null
+++ b/src/mesa/main/conservativeraster.c
@@ -0,0 +1,127 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2018 Rhys Perry
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file conservativeraster.c
+ * glConservativeRasterParameteriNV and glConservativeRasterParameterfNV functions
+ */
+
+#include "conservativeraster.h"
+#include "context.h"
+#include "enums.h"
+
+static ALWAYS_INLINE void
+conservative_raster_parameter(GLenum pname, GLdouble param,
+                              bool no_error, const char *func)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (!ctx->Extensions.NV_conservative_raster_dilate &&
+       !ctx->Extensions.NV_conservative_raster_pre_snap_triangles) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, func);
+      return;
+   }
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "%s(%s, %g)\n",
+                  func, _mesa_enum_to_string(pname), param);
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   switch (pname) {
+   case GL_CONSERVATIVE_RASTER_DILATE_NV:
+      if (!ctx->Extensions.NV_conservative_raster_dilate) {
+         _mesa_error(ctx, GL_INVALID_OPERATION, func);
+         return;
+      }
+
+      if (param < 0.0) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "%s(param=%g)", func, param);
+         return;
+      }
+      param = CLAMP(param,
+                    ctx->Const.ConservativeRasterDilateRange[0],
+                    ctx->Const.ConservativeRasterDilateRange[1]);
+      ctx->ConservativeRasterDilate = param;
+      break;
+   case GL_CONSERVATIVE_RASTER_MODE_NV:
+      if (!ctx->Extensions.NV_conservative_raster_pre_snap_triangles) {
+         _mesa_error(ctx, GL_INVALID_OPERATION, func);
+         return;
+      }
+
+      if (param!=GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV &&
+          param!=GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV) {
+         _mesa_error(ctx, GL_INVALID_ENUM,
+                     "%s(param=%s)", func, _mesa_enum_to_string(param));
+         return;
+      }
+      ctx->ConservativeRasterMode = param;
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)",
+                  func, _mesa_enum_to_string(pname));
+      return;
+   }
+
+   FLUSH_VERTICES(ctx, 0);
+   ctx->NewDriverState |=
+      ctx->DriverFlags.NewNvConservativeRasterizationParams;
+}
+
+void GLAPIENTRY
+_mesa_ConservativeRasterParameteriNV_no_error(GLenum pname, GLint param)
+{
+   conservative_raster_parameter(pname, param, true, 
+                                 "glConservativeRasterParameteriNV");
+}
+
+void GLAPIENTRY
+_mesa_ConservativeRasterParameteriNV(GLenum pname, GLint param)
+{
+   conservative_raster_parameter(pname, param, false,
+                                 "glConservativeRasterParameteriNV");
+}
+
+void GLAPIENTRY
+_mesa_ConservativeRasterParameterfNV_no_error(GLenum pname, GLfloat param)
+{
+   conservative_raster_parameter(pname, param, true, 
+                                 "glConservativeRasterParameterfNV");
+}
+
+void GLAPIENTRY
+_mesa_ConservativeRasterParameterfNV(GLenum pname, GLfloat param)
+{
+   conservative_raster_parameter(pname, param, false, 
+                                 "glConservativeRasterParameterfNV");
+}
+
+void
+_mesa_init_conservative_raster(struct gl_context *ctx)
+{
+   ctx->ConservativeRasterDilate = 0.0;
+   ctx->ConservativeRasterMode = GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV;
+}
diff --git a/src/mesa/main/conservativeraster.h b/src/mesa/main/conservativeraster.h
new file mode 100644
index 0000000000..1865cfc2a4
--- /dev/null
+++ b/src/mesa/main/conservativeraster.h
@@ -0,0 +1,48 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2018 Rhys Perry
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef CONSERVATIVERASTER_H
+#define CONSERVATIVERASTER_H
+
+#include "glheader.h"
+
+struct gl_context;
+
+extern void GLAPIENTRY
+_mesa_ConservativeRasterParameteriNV_no_error(GLenum pname, GLint param);
+
+extern void GLAPIENTRY
+_mesa_ConservativeRasterParameteriNV(GLenum pname, GLint param);
+
+extern void GLAPIENTRY
+_mesa_ConservativeRasterParameterfNV_no_error(GLenum pname, GLfloat param);
+
+extern void GLAPIENTRY
+_mesa_ConservativeRasterParameterfNV(GLenum pname, GLfloat param);
+
+extern void
+_mesa_init_conservative_raster(struct gl_context *ctx);
+
+#endif
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index e13343b5e6..9a4bf8d394 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -87,6 +87,7 @@
 #include "blend.h"
 #include "buffers.h"
 #include "bufferobj.h"
+#include "conservativeraster.h"
 #include "context.h"
 #include "cpuinfo.h"
 #include "debug.h"
@@ -739,6 +740,14 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api)
    consts->MaxComputeVariableGroupSize[1] = 512;
    consts->MaxComputeVariableGroupSize[2] = 64;
    consts->MaxComputeVariableGroupInvocations = 512;
+
+   /** GL_NV_conservative_raster */
+   consts->MaxSubpixelPrecisionBiasBits = 0;
+
+   /** GL_NV_conservative_raster_dilate */
+   consts->ConservativeRasterDilateRange[0] = 0.0;
+   consts->ConservativeRasterDilateRange[0] = 0.0;
+   consts->ConservativeRasterDilateGranularity = 0.0;
 }
 
 
@@ -828,6 +837,7 @@ init_attrib_groups(struct gl_context *ctx)
    _mesa_init_bbox( ctx );
    _mesa_init_buffer_objects( ctx );
    _mesa_init_color( ctx );
+   _mesa_init_conservative_raster( ctx );
    _mesa_init_current( ctx );
    _mesa_init_depth( ctx );
    _mesa_init_debug( ctx );
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 2086611aa3..1929cdf2af 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -488,6 +488,15 @@ typedef enum
    /* EXT_window_rectangles */
    OPCODE_WINDOW_RECTANGLES,
 
+   /* NV_conservative_raster */
+   OPCODE_SUBPIXEL_PRECISION_BIAS,
+
+   /* NV_conservative_raster_dilate */
+   OPCODE_CONSERVATIVE_RASTER_PARAMETER_F,
+
+   /* NV_conservative_raster_pre_snap_triangles */
+   OPCODE_CONSERVATIVE_RASTER_PARAMETER_I,
+
    /* The following three are meta instructions */
    OPCODE_ERROR,                /* raise compiled-in error */
    OPCODE_CONTINUE,
@@ -7928,6 +7937,59 @@ save_WindowRectanglesEXT(GLenum mode, GLsizei count, const GLint *box)
    }
 }
 
+
+/** GL_NV_conservative_raster */
+static void GLAPIENTRY
+save_SubpixelPrecisionBiasNV(GLuint xbits, GLuint ybits)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_SUBPIXEL_PRECISION_BIAS, 2);
+   if (n) {
+      n[1].ui = xbits;
+      n[2].ui = ybits;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_SubpixelPrecisionBiasNV(ctx->Exec, (xbits, ybits));
+   }
+}
+
+/** GL_NV_conservative_raster_dilate */
+static void GLAPIENTRY
+save_ConservativeRasterParameterfNV(GLenum pname, GLfloat param)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_CONSERVATIVE_RASTER_PARAMETER_F, 2);
+   if (n) {
+      n[1].e = pname;
+      n[2].f = param;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ConservativeRasterParameterfNV(ctx->Exec, (pname, param));
+   }
+}
+
+/** GL_NV_conservative_raster_pre_snap_triangles */
+static void GLAPIENTRY
+save_ConservativeRasterParameteriNV(GLenum pname, GLint param)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_CONSERVATIVE_RASTER_PARAMETER_I, 2);
+   if (n) {
+      n[1].e = pname;
+      n[2].i = param;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_ConservativeRasterParameteriNV(ctx->Exec, (pname, param));
+   }
+}
+
+
 /**
  * Save an error-generating command into display list.
  *
@@ -9137,6 +9199,21 @@ execute_list(struct gl_context *ctx, GLuint list)
                   ctx->Exec, (n[1].e, n[2].si, get_pointer(&n[3])));
             break;
 
+         /* GL_NV_conservative_raster */
+         case OPCODE_SUBPIXEL_PRECISION_BIAS:
+            CALL_SubpixelPrecisionBiasNV(ctx->Exec, (n[1].ui, n[2].ui));
+            break;
+
+         /* GL_NV_conservative_raster_dilate */
+         case OPCODE_CONSERVATIVE_RASTER_PARAMETER_F:
+            CALL_ConservativeRasterParameterfNV(ctx->Exec, (n[1].e, n[2].f));
+            break;
+
+         /* GL_NV_conservative_raster_pre_snap_triangles */
+         case OPCODE_CONSERVATIVE_RASTER_PARAMETER_I:
+            CALL_ConservativeRasterParameteriNV(ctx->Exec, (n[1].e, n[2].i));
+            break;
+
          case OPCODE_CONTINUE:
             n = (Node *) get_pointer(&n[1]);
             break;
@@ -10049,6 +10126,15 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
 
    /* GL_EXT_window_rectangles */
    SET_WindowRectanglesEXT(table, save_WindowRectanglesEXT);
+
+   /* GL_NV_conservative_raster */
+   SET_SubpixelPrecisionBiasNV(table, save_SubpixelPrecisionBiasNV);
+
+   /* GL_NV_conservative_raster_dilate */
+   SET_ConservativeRasterParameterfNV(table, save_ConservativeRasterParameterfNV);
+
+   /* GL_NV_conservative_raster_pre_snap_triangles */
+   SET_ConservativeRasterParameteriNV(table, save_ConservativeRasterParameteriNV);
 }
 
 
diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
index 7625a4c957..84f036071a 100644
--- a/src/mesa/main/enable.c
+++ b/src/mesa/main/enable.c
@@ -482,6 +482,16 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
             ctx->DriverFlags.NewIntelConservativeRasterization;
          ctx->IntelConservativeRasterization = state;
          break;
+      case GL_CONSERVATIVE_RASTERIZATION_NV:
+         if (!_mesa_has_NV_conservative_raster(ctx))
+            goto invalid_enum_error;
+         if (ctx->ConservativeRasterization == state)
+            return;
+         FLUSH_VERTICES(ctx, 0);
+         ctx->NewDriverState |=
+            ctx->DriverFlags.NewNvConservativeRasterization;
+         ctx->ConservativeRasterization = state;
+         break;
       case GL_COLOR_LOGIC_OP:
          if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES)
             goto invalid_enum_error;
@@ -1750,6 +1760,10 @@ _mesa_IsEnabled( GLenum cap )
          CHECK_EXTENSION(INTEL_conservative_rasterization);
          return ctx->IntelConservativeRasterization;
 
+      case GL_CONSERVATIVE_RASTERIZATION_NV:
+         CHECK_EXTENSION(NV_conservative_raster);
+         return ctx->ConservativeRasterization;
+
       case GL_TILE_RASTER_ORDER_FIXED_MESA:
          CHECK_EXTENSION(MESA_tile_raster_order);
          return ctx->TileRasterOrderFixed;
diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h
index 492f7c3d20..5a57fb7a40 100644
--- a/src/mesa/main/extensions_table.h
+++ b/src/mesa/main/extensions_table.h
@@ -332,6 +332,10 @@ EXT(NVX_gpu_memory_info                     , NVX_gpu_memory_info
 
 EXT(NV_blend_square                         , dummy_true                             , GLL,  x ,  x ,  x , 1999)
 EXT(NV_conditional_render                   , NV_conditional_render                  , GLL, GLC,  x ,  x , 2008)
+EXT(NV_conservative_raster                  , NV_conservative_raster                 , GLL, GLC, ES1, ES2, 2015)
+EXT(NV_conservative_raster_dilate           , NV_conservative_raster_dilate          , GLL, GLC, ES1, ES2, 2015)
+EXT(NV_conservative_raster_pre_snap         , NV_conservative_raster_pre_snap        , GLL, GLC, ES1, ES2, 2017)
+EXT(NV_conservative_raster_pre_snap_triangles, NV_conservative_raster_pre_snap_triangles, GLL, GLC, ES1, ES2, 2015)
 EXT(NV_depth_clamp                          , ARB_depth_clamp                        , GLL, GLC,  x ,  x , 2001)
 EXT(NV_draw_buffers                         , dummy_true                             ,  x ,  x ,  x , ES2, 2011)
 EXT(NV_fbo_color_attachments                , dummy_true                             ,  x ,  x ,  x , ES2, 2010)
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 90ab7ca60f..44b7b838a3 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -506,6 +506,9 @@ EXTRA_EXT(OES_primitive_bounding_box);
 EXTRA_EXT(ARB_compute_variable_group_size);
 EXTRA_EXT(KHR_robustness);
 EXTRA_EXT(ARB_sparse_buffer);
+EXTRA_EXT(NV_conservative_raster);
+EXTRA_EXT(NV_conservative_raster_dilate);
+EXTRA_EXT(NV_conservative_raster_pre_snap_triangles);
 
 static const int
 extra_ARB_color_buffer_float_or_glcore[] = {
diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py
index f38a87df88..de5fed6fc1 100644
--- a/src/mesa/main/get_hash_params.py
+++ b/src/mesa/main/get_hash_params.py
@@ -355,6 +355,19 @@ descriptor=[
 # GL_ARB_robustness / GL_KHR_robustness
   [ "CONTEXT_ROBUST_ACCESS", "CONTEXT_ENUM16(Const.RobustAccess), extra_KHR_robustness" ],
   [ "RESET_NOTIFICATION_STRATEGY_ARB", "CONTEXT_ENUM16(Const.ResetStrategy), extra_KHR_robustness_or_GL" ],
+
+# GL_NV_conservative_raster
+  [ "SUBPIXEL_PRECISION_BIAS_X_BITS_NV", "CONTEXT_UINT(SubpixelPrecisionBias[0]), extra_NV_conservative_raster" ],
+  [ "SUBPIXEL_PRECISION_BIAS_Y_BITS_NV", "CONTEXT_UINT(SubpixelPrecisionBias[1]), extra_NV_conservative_raster" ],
+  [ "MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV", "CONTEXT_UINT(Const.MaxSubpixelPrecisionBiasBits), extra_NV_conservative_raster" ],
+
+# GL_NV_conservative_raster_dilate
+  [ "CONSERVATIVE_RASTER_DILATE_RANGE_NV", "CONTEXT_FLOAT2(Const.ConservativeRasterDilateRange), extra_NV_conservative_raster_dilate" ],
+  [ "CONSERVATIVE_RASTER_DILATE_GRANULARITY_NV", "CONTEXT_FLOAT(Const.ConservativeRasterDilateGranularity), extra_NV_conservative_raster_dilate" ],
+  [ "CONSERVATIVE_RASTER_DILATE_NV", "CONTEXT_FLOAT(ConservativeRasterDilate), extra_NV_conservative_raster_dilate" ],
+
+# GL_NV_conservative_raster_pre_snap_triangles
+  [ "CONSERVATIVE_RASTER_MODE_NV", "CONTEXT_ENUM16(ConservativeRasterMode), extra_NV_conservative_raster_pre_snap_triangles" ],
 ]},
 
 # GLES3 is not a typo.
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index b7a7b34a09..88932e0f65 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -4141,6 +4141,13 @@ struct gl_constants
    /** GL_ARB_get_program_binary */
    GLuint NumProgramBinaryFormats;
 
+   /** GL_NV_conservative_raster */
+   GLuint MaxSubpixelPrecisionBiasBits;
+
+   /** GL_NV_conservative_raster_dilate */
+   GLfloat ConservativeRasterDilateRange[2];
+   GLfloat ConservativeRasterDilateGranularity;
+
    /** Is the drivers uniform storage packed or padded to 16 bytes. */
    bool PackedDriverUniformStorage;
 
@@ -4358,6 +4365,10 @@ struct gl_extensions
    GLboolean NV_texture_env_combine4;
    GLboolean NV_texture_rectangle;
    GLboolean NV_vdpau_interop;
+   GLboolean NV_conservative_raster;
+   GLboolean NV_conservative_raster_dilate;
+   GLboolean NV_conservative_raster_pre_snap_triangles;
+   GLboolean NV_conservative_raster_pre_snap;
    GLboolean NVX_gpu_memory_info;
    GLboolean TDFX_texture_compression_FXT1;
    GLboolean OES_EGL_image;
@@ -4631,6 +4642,17 @@ struct gl_driver_flags
     */
    uint64_t NewIntelConservativeRasterization;
 
+   /**
+    * gl_context::NvConservativeRasterization
+    */
+   uint64_t NewNvConservativeRasterization;
+
+   /**
+    * gl_context::ConservativeRasterMode/ConservativeRasterDilate
+    * gl_context::SubpixelPrecisionBias
+    */
+   uint64_t NewNvConservativeRasterizationParams;
+
    /**
     * gl_context::Scissor::WindowRects
     */
@@ -4939,6 +4961,7 @@ struct gl_context
    struct gl_texture_attrib	Texture;	/**< Texture attributes */
    struct gl_transform_attrib	Transform;	/**< Transformation attributes */
    struct gl_viewport_attrib	ViewportArray[MAX_VIEWPORTS];	/**< Viewport attributes */
+   GLuint			SubpixelPrecisionBias[2];	/**< Viewport attributes */
    /*@}*/
 
    /** \name Client attribute stack */
@@ -5119,7 +5142,10 @@ struct gl_context
    GLboolean TextureFormatSupported[MESA_FORMAT_COUNT];
 
    GLboolean RasterDiscard;  /**< GL_RASTERIZER_DISCARD */
-   GLboolean IntelConservativeRasterization; /**< GL_INTEL_CONSERVATIVE_RASTERIZATION */
+   GLboolean IntelConservativeRasterization; /**< GL_CONSERVATIVE_RASTERIZATION_INTEL */
+   GLboolean ConservativeRasterization; /**< GL_CONSERVATIVE_RASTERIZATION_NV */
+   GLfloat ConservativeRasterDilate;
+   GLenum16 ConservativeRasterMode;
 
    /** Does glVertexAttrib(0) alias glVertex()? */
    bool _AttribZeroAliasesVertex;
diff --git a/src/mesa/main/tests/dispatch_sanity.cpp b/src/mesa/main/tests/dispatch_sanity.cpp
index 83a4b04654..b1413907de 100644
--- a/src/mesa/main/tests/dispatch_sanity.cpp
+++ b/src/mesa/main/tests/dispatch_sanity.cpp
@@ -1026,6 +1026,15 @@ const struct function common_desktop_functions_possible[] = {
    /* GL_EXT_shader_framebuffer_fetch_non_coherent */
    { "glFramebufferFetchBarrierEXT", 20, -1 },
 
+   /* GL_NV_conservative_raster */
+   { "glSubpixelPrecisionBiasNV", 10, -1 },
+
+   /* GL_NV_conservative_raster_dilate */
+   { "glConservativeRasterParameterfNV", 10, -1 },
+
+   /* GL_NV_conservative_raster_pre_snap_triangles */
+   { "glConservativeRasterParameteriNV", 10, -1 },
+
    { NULL, 0, -1 }
 };
 
@@ -2185,6 +2194,15 @@ const struct function gles11_functions_possible[] = {
    /* GL_EXT_polygon_offset_clamp */
    { "glPolygonOffsetClampEXT", 11, -1 },
 
+   /* GL_NV_conservative_raster */
+   { "glSubpixelPrecisionBiasNV", 20, -1 },
+
+   /* GL_NV_conservative_raster_dilate */
+   { "glConservativeRasterParameterfNV", 20, -1 },
+
+   /* GL_NV_conservative_raster_pre_snap_triangles */
+   { "glConservativeRasterParameteriNV", 20, -1 },
+
    { NULL, 0, -1 }
 };
 
@@ -2452,6 +2470,15 @@ const struct function gles2_functions_possible[] = {
    /* GL_EXT_shader_framebuffer_fetch_non_coherent */
    { "glFramebufferFetchBarrierEXT", 20, -1 },
 
+   /* GL_NV_conservative_raster */
+   { "glSubpixelPrecisionBiasNV", 20, -1 },
+
+   /* GL_NV_conservative_raster_dilate */
+   { "glConservativeRasterParameterfNV", 20, -1 },
+
+   /* GL_NV_conservative_raster_pre_snap_triangles */
+   { "glConservativeRasterParameteriNV", 20, -1 },
+
    { NULL, 0, -1 }
 };
 
diff --git a/src/mesa/main/viewport.c b/src/mesa/main/viewport.c
index 398cc63685..b439521342 100644
--- a/src/mesa/main/viewport.c
+++ b/src/mesa/main/viewport.c
@@ -489,6 +489,9 @@ void _mesa_init_viewport(struct gl_context *ctx)
       ctx->ViewportArray[i].Near = 0.0;
       ctx->ViewportArray[i].Far = 1.0;
    }
+
+   ctx->SubpixelPrecisionBias[0] = 0;
+   ctx->SubpixelPrecisionBias[1] = 0;
 }
 
 
@@ -599,3 +602,57 @@ _mesa_get_viewport_xform(struct gl_context *ctx, unsigned i,
       translate[2] = n;
    }
 }
+
+
+static void
+subpixel_precision_bias(struct gl_context *ctx, GLuint xbits, GLuint ybits)
+{
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glSubpixelPrecisionBiasNV(%u, %u)\n", xbits, ybits);
+
+   ctx->SubpixelPrecisionBias[0] = xbits;
+   ctx->SubpixelPrecisionBias[1] = ybits;
+
+   FLUSH_VERTICES(ctx, 0);
+   ctx->NewDriverState |=
+      ctx->DriverFlags.NewNvConservativeRasterizationParams;
+}
+
+void GLAPIENTRY
+_mesa_SubpixelPrecisionBiasNV_no_error(GLuint xbits, GLuint ybits)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glSubpixelPrecisionBiasNV(%u, %u)\n", xbits, ybits);
+
+   subpixel_precision_bias(ctx, xbits, ybits);
+}
+
+void GLAPIENTRY
+_mesa_SubpixelPrecisionBiasNV(GLuint xbits, GLuint ybits)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glSubpixelPrecisionBiasNV(%u, %u)\n", xbits, ybits);
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (!ctx->Extensions.NV_conservative_raster) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glSubpixelPrecisionBiasNV");
+      return;
+   }
+
+   if (xbits > ctx->Const.MaxSubpixelPrecisionBiasBits) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glSubpixelPrecisionBiasNV");
+      return;
+   }
+
+   if (ybits > ctx->Const.MaxSubpixelPrecisionBiasBits) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glSubpixelPrecisionBiasNV");
+      return;
+   }
+
+   subpixel_precision_bias(ctx, xbits, ybits);
+}
diff --git a/src/mesa/main/viewport.h b/src/mesa/main/viewport.h
index 5860e4f5dc..aca62965b0 100644
--- a/src/mesa/main/viewport.h
+++ b/src/mesa/main/viewport.h
@@ -104,4 +104,10 @@ extern void
 _mesa_get_viewport_xform(struct gl_context *ctx, unsigned i,
                          float scale[3], float translate[3]);
 
+extern void GLAPIENTRY
+_mesa_SubpixelPrecisionBiasNV_no_error(GLuint xbits, GLuint ybits);
+
+extern void GLAPIENTRY
+_mesa_SubpixelPrecisionBiasNV(GLuint xbits, GLuint ybits);
+
 #endif
diff --git a/src/mesa/meson.build b/src/mesa/meson.build
index d2d058bfa3..6f61670cbc 100644
--- a/src/mesa/meson.build
+++ b/src/mesa/meson.build
@@ -100,6 +100,8 @@ files_libmesa_common = files(
   'main/condrender.c',
   'main/condrender.h',
   'main/config.h',
+  'main/conservativeraster.c',
+  'main/conservativeraster.h',
   'main/context.c',
   'main/context.h',
   'main/convolve.c',
-- 
2.14.3



More information about the mesa-dev mailing list