[Mesa-dev] [PATCH 4v2 /4] nvc0: add conservative rasterization support (v2)

Rhys Perry pendingchaos02 at gmail.com
Thu Mar 22 14:40:04 UTC 2018


Subpixel precision bias, dilation and the post-snap mode are supported on
GM200 and newer. The pre-snap mode is supported for triangle primitives on
GP100.

v2: fix code to handle earlier hardware

---
 src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h       |  5 +++++
 src/gallium/drivers/nouveau/nvc0/nvc0_screen.c       | 18 ++++++++++++------
 src/gallium/drivers/nouveau/nvc0/nvc0_state.c        | 20 ++++++++++++++++++++
 .../drivers/nouveau/nvc0/nvc0_state_validate.c       |  7 +++++++
 src/gallium/drivers/nouveau/nvc0/nvc0_stateobj.h     |  2 +-
 5 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h b/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h
index d7245fbcae..c5456e48b5 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h
@@ -447,6 +447,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NVC0_3D_VIEWPORT_TRANSLATE_Z__ESIZE			0x00000020
 #define NVC0_3D_VIEWPORT_TRANSLATE_Z__LEN			0x00000010
 
+#define NVC0_3D_SUBPIXEL_PRECISION(i0)			       (0x00000a1c + 0x20*(i0))
+#define NVC0_3D_SUBPIXEL_PRECISION__ESIZE			0x00000020
+#define NVC0_3D_SUBPIXEL_PRECISION__LEN				0x00000010
+
 #define NVC0_3D_VIEWPORT_HORIZ(i0)			       (0x00000c00 + 0x10*(i0))
 #define NVC0_3D_VIEWPORT_HORIZ__ESIZE				0x00000010
 #define NVC0_3D_VIEWPORT_HORIZ__LEN				0x00000010
@@ -780,6 +784,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NVC0_3D_UNK1140					0x00001140
 
 #define NVC0_3D_UNK1144					0x00001144
+#define NVC0_3D_CONSERVATIVE_RASTER			0x00001148
 
 #define NVC0_3D_VTX_ATTR_DEFINE				0x0000114c
 #define NVC0_3D_VTX_ATTR_DEFINE_ATTR__MASK			0x000000ff
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index ddbb3ec16d..b2b87e01d6 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -172,6 +172,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
       return 30;
    case PIPE_CAP_MAX_WINDOW_RECTANGLES:
       return NVC0_MAX_WINDOW_RECTANGLES;
+   case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS:
+      return class_3d>=GM200_3D_CLASS ? 8 : 0;
 
    /* supported caps */
    case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
@@ -263,7 +265,12 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
    case PIPE_CAP_TGSI_TES_LAYER_VIEWPORT:
    case PIPE_CAP_POST_DEPTH_COVERAGE:
+   case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_TRIANGLES:
+   case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_POINTS_LINES:
+   case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE:
       return class_3d >= GM200_3D_CLASS;
+   case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_TRIANGLES:
+      return class_3d >= GP100_3D_CLASS;
    case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
    case PIPE_CAP_TGSI_BALLOT:
    case PIPE_CAP_BINDLESS_TEXTURE:
@@ -309,12 +316,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_FENCE_SIGNAL:
    case PIPE_CAP_CONSTBUF0_FLAGS:
    case PIPE_CAP_PACKED_UNIFORMS:
-   case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_TRIANGLES:
-   case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_POINTS_LINES:
-   case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_TRIANGLES:
    case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES:
-   case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE:
-   case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
@@ -444,6 +446,8 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen,
 static float
 nvc0_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
 {
+   const uint16_t class_3d = nouveau_screen(pscreen)->class_3d;
+
    switch (param) {
    case PIPE_CAPF_MAX_LINE_WIDTH:
    case PIPE_CAPF_MAX_LINE_WIDTH_AA:
@@ -457,9 +461,11 @@ nvc0_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
    case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
       return 15.0f;
    case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
+      return 0.0f;
    case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
+      return class_3d>=GM200_3D_CLASS ? 0.75f : 0.0f;
    case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
-      return 0.0f;
+      return class_3d>=GM200_3D_CLASS ? 0.25f : 0.0f;
    }
 
    NOUVEAU_ERR("unknown PIPE_CAPF %d\n", param);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
index 99d45a238a..312d7d1de7 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
@@ -324,6 +324,26 @@ nvc0_rasterizer_state_create(struct pipe_context *pipe,
 
     SB_IMMED_3D(so, PIXEL_CENTER_INTEGER, !cso->half_pixel_center);
 
+    if (class_3d >= GM200_3D_CLASS) {
+        if (cso->conservative_raster_mode != PIPE_CONSERVATIVE_RASTER_OFF) {
+            uint32_t value = (uint32_t)(cso->conservative_raster_dilate*4)<<23;
+            bool post_snap = cso->conservative_raster_mode ==
+                PIPE_CONSERVATIVE_RASTER_POST_SNAP;
+            if (post_snap || class_3d<GP100_3D_CLASS) value |= 0x2000000;
+
+            SB_IMMED_3D(so, CONSERVATIVE_RASTER, 1);
+
+            SB_DATA(so, NVC0_FIFO_PKHDR_SQ(SUBC_3D(NVC0_GRAPH_SCRATCH(0)), 3));
+            SB_DATA(so, 0);
+            SB_DATA(so, value);
+            SB_DATA(so, 0x3800000); //Write mask
+            SB_BEGIN_3D(so, FIRMWARE(4), 1);
+            SB_DATA    (so, 0x418800);
+        } else {
+            SB_IMMED_3D(so, CONSERVATIVE_RASTER, 0);
+        }
+    }
+
     assert(so->size <= ARRAY_SIZE(so->state));
     return (void *)so;
 }
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
index 37a6761958..8868f24e62 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
@@ -339,6 +339,13 @@ nvc0_validate_viewport(struct nvc0_context *nvc0)
       BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(i)), 2);
       PUSH_DATAf(push, zmin);
       PUSH_DATAf(push, zmax);
+
+      /* Only applies when conservative rasterization is enabled */
+      if (nvc0->screen->base.class_3d >= GM200_3D_CLASS) {
+         uint16_t prec_bias = vp->subpixel_precision[0];
+         prec_bias |= vp->subpixel_precision[1] << 8;
+         IMMED_NVC0(push, NVC0_3D(SUBPIXEL_PRECISION(i)), prec_bias);
+      }
    }
    nvc0->viewports_dirty = 0;
 }
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_stateobj.h b/src/gallium/drivers/nouveau/nvc0/nvc0_stateobj.h
index 3006ed6195..892864eac4 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_stateobj.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_stateobj.h
@@ -23,7 +23,7 @@ struct nvc0_blend_stateobj {
 struct nvc0_rasterizer_stateobj {
    struct pipe_rasterizer_state pipe;
    int size;
-   uint32_t state[43];
+   uint32_t state[50];
 };
 
 struct nvc0_zsa_stateobj {
-- 
2.14.3



More information about the mesa-dev mailing list