From 07dac3e04056f7e90661eeb39aea66ba0b82538d Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Sat, 7 Apr 2018 16:15:00 -0600 Subject: [PATCH] nvc0: add conservative rasterization support 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. Signed-off-by: Rhys Perry Reviewed-by: Ilia Mirkin --- .../drivers/nouveau/nvc0/mme/com9097.mme | 30 +++++++++++++++++++ .../drivers/nouveau/nvc0/mme/com9097.mme.h | 21 +++++++++++++ .../drivers/nouveau/nvc0/nvc0_3d.xml.h | 5 ++++ .../drivers/nouveau/nvc0/nvc0_macros.h | 4 ++- .../drivers/nouveau/nvc0/nvc0_screen.c | 19 ++++++++---- src/gallium/drivers/nouveau/nvc0/nvc0_state.c | 14 +++++++++ .../drivers/nouveau/nvc0/nvc0_stateobj.h | 2 +- 7 files changed, 87 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme b/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme index 7c5ec8f52b9..ecf99606672 100644 --- a/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme +++ b/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme @@ -550,3 +550,33 @@ qbw_postclamp: qbw_done: exit send (extrinsrt 0x0 $r4 0x0 0x10 0x10) maddrsend 0x44 + +/* NVC0_3D_MACRO_CONSERVATIVE_RASTER_STATE: + * + * This sets basically all the conservative rasterization state. It sets + * CONSERVATIVE_RASTER to one while doing so. + * + * arg = biasx | biasy<<4 | (dilation*4)<<8 | mode<<10 + */ +.section #mme9097_conservative_raster_state + /* Mode and dilation */ + maddr 0x1d00 /* SCRATCH[0] */ + send 0x0 /* unknown */ + send (extrinsrt 0x0 $r1 8 3 23) /* value */ + mov $r2 0x7 + send (extrinsrt 0x0 $r2 0 3 23) /* write mask */ + maddr 0x18c4 /* FIRMWARE[4] */ + mov $r2 0x831 + send (extrinsrt 0x0 $r2 0 12 11) /* sends 0x418800 */ + /* Subpixel precision */ + mov $r2 (extrinsrt 0x0 $r1 0 3 0) + mov $r2 (extrinsrt $r2 $r1 4 4 8) + maddr 0x8287 /* SUBPIXEL_PRECISION[0] (incrementing by 8 methods) */ + mov $r3 16 /* loop counter */ +crs_loop: + mov $r3 (add $r3 -1) + branz $r3 #crs_loop + send $r2 + /* Enable */ + exit maddr 0x1452 /* CONSERVATIVE_RASTER */ + send 0x1 diff --git a/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme.h b/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme.h index 9618da6e28c..3eacda9a27a 100644 --- a/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme.h +++ b/src/gallium/drivers/nouveau/nvc0/mme/com9097.mme.h @@ -373,3 +373,24 @@ uint32_t mme9097_query_buffer_write[] = { 0x840100c2, 0x00110071, }; + +uint32_t mme9097_conservative_raster_state[] = { + 0x07400021, + 0x00000041, + 0xb8d04042, +/* 0x000c: crs_loop */ + 0x0001c211, + 0xb8c08042, + 0x06310021, + 0x020c4211, + 0x5b008042, + 0x00c04212, + 0x41085212, + 0x20a1c021, + 0x00040311, + 0xffffdb11, + 0xffffd817, + 0x00001041, + 0x051480a1, + 0x00004041, +}; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h b/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h index d7245fbcae1..c5456e48b58 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_macros.h b/src/gallium/drivers/nouveau/nvc0/nvc0_macros.h index eeacc714f3e..7aa06337950 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_macros.h +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_macros.h @@ -35,6 +35,8 @@ #define NVC0_3D_MACRO_QUERY_BUFFER_WRITE 0x00003858 -#define NVC0_CP_MACRO_LAUNCH_GRID_INDIRECT 0x00003860 +#define NVC0_CP_MACRO_LAUNCH_GRID_INDIRECT 0x00003860 + +#define NVC0_3D_MACRO_CONSERVATIVE_RASTER_STATE 0x00003868 #endif /* __NVC0_MACROS_H__ */ diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index 37e43f02e36..e1c7b3a2364 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: @@ -264,7 +266,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); @@ -1207,6 +1213,7 @@ nvc0_screen_create(struct nouveau_device *dev) MK_MACRO(NVC0_3D_MACRO_DRAW_ARRAYS_INDIRECT_COUNT, mme9097_draw_arrays_indirect_count); MK_MACRO(NVC0_3D_MACRO_DRAW_ELEMENTS_INDIRECT_COUNT, mme9097_draw_elts_indirect_count); MK_MACRO(NVC0_3D_MACRO_QUERY_BUFFER_WRITE, mme9097_query_buffer_write); + MK_MACRO(NVC0_3D_MACRO_CONSERVATIVE_RASTER_STATE, mme9097_conservative_raster_state); MK_MACRO(NVC0_CP_MACRO_LAUNCH_GRID_INDIRECT, mme90c0_launch_grid_indirect); BEGIN_NVC0(push, NVC0_3D(RASTERIZE_ENABLE), 1); diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c index 3e204f09a4d..37dbbe66c7c 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c @@ -327,6 +327,20 @@ 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) { + bool post_snap = cso->conservative_raster_mode == + PIPE_CONSERVATIVE_RASTER_POST_SNAP; + uint32_t state = cso->subpixel_precision_x; + state |= cso->subpixel_precision_y << 4; + state |= (uint32_t)(cso->conservative_raster_dilate * 4) << 8; + state |= (post_snap || class_3d < GP100_3D_CLASS) ? 1 << 10 : 0; + SB_IMMED_3D(so, MACRO_CONSERVATIVE_RASTER_STATE, state); + } 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_stateobj.h b/src/gallium/drivers/nouveau/nvc0/nvc0_stateobj.h index 3006ed61956..e20032845cd 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[44]; }; struct nvc0_zsa_stateobj { -- 2.30.2