gallium: add a pipe cap for determining driver support for prim type in restarts
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Fri, 21 May 2021 11:25:40 +0000 (07:25 -0400)
committerMarge Bot <eric+marge@anholt.net>
Wed, 23 Jun 2021 03:13:41 +0000 (03:13 +0000)
this is another prim type bitmask which will trigger automatic draw rewriting
to a direct draw any time a prim-restart draw occurs with a prim type that is
not supported by the driver for prim restart, even if that prim type is supported
for normal drawing

the default is set to all prim types to preserve existing functionality, and PrimitiveRestartForPatches
is now explicitly set to false because no driver supports it

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10973>

docs/gallium/screen.rst
src/gallium/auxiliary/util/u_screen.c
src/gallium/auxiliary/util/u_vbuf.c
src/gallium/auxiliary/util/u_vbuf.h
src/gallium/drivers/nouveau/nv30/nv30_screen.c
src/gallium/drivers/nouveau/nv50/nv50_screen.c
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
src/gallium/include/pipe/p_defines.h
src/mesa/state_tracker/st_extensions.c

index 19dd294..96914e5 100644 (file)
@@ -617,6 +617,7 @@ The integer capabilities:
 * ``PIPE_CAP_SAMPLER_REDUCTION_MINMAX_ARB``: Driver supports ARB min/max sampler reduction with format queries.
 * ``PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART``: Driver requests all draws using a non-fixed restart index to be rewritten to use a fixed restart index.
 * ``PIPE_CAP_SUPPORTED_PRIM_MODES``: A bitmask of the ``pipe_prim_type`` enum values that the driver can natively support.
+* ``PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART``: A bitmask of the ``pipe_prim_type`` enum values that the driver can natively support for primitive restart. Only useful if ``PIPE_CAP_PRIMITIVE_RESTART`` is also exported. ``PIPE_PRIM_PATCHES`` must be supported to prevent incorrect lowering of primitive restart.
 
 .. _pipe_capf:
 
index 70ac8a9..f682eed 100644 (file)
@@ -87,6 +87,7 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen,
    case PIPE_CAP_RGB_OVERRIDE_DST_ALPHA_BLEND:
       return 0;
 
+   case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART:
    case PIPE_CAP_SUPPORTED_PRIM_MODES:
       return BITFIELD_MASK(PIPE_PRIM_MAX);
 
@@ -272,7 +273,6 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen,
    case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
    case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
    case PIPE_CAP_CULL_DISTANCE:
-   case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
    case PIPE_CAP_TGSI_VOTE:
    case PIPE_CAP_MAX_WINDOW_RECTANGLES: /* Enables EXT_window_rectangles */
    case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
index c09f785..513b79b 100644 (file)
@@ -308,6 +308,7 @@ void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps,
    if (screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART) ||
        screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX)) {
       caps->rewrite_restart_index = screen->get_param(screen, PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART);
+      caps->supported_restart_modes = screen->get_param(screen, PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART);
       caps->fallback_always |= caps->rewrite_restart_index;
    }
    caps->supported_prim_modes = screen->get_param(screen, PIPE_CAP_SUPPORTED_PRIM_MODES);
@@ -338,11 +339,13 @@ u_vbuf_create(struct pipe_context *pipe, struct u_vbuf_caps *caps)
    mgr->caps = *caps;
    mgr->pipe = pipe;
    if (caps->rewrite_ubyte_ibs || caps->rewrite_restart_index ||
-       (caps->supported_prim_modes & BITFIELD_MASK(PIPE_PRIM_MAX)) != BITFIELD_MASK(PIPE_PRIM_MAX)) {
+       /* require all but patches */
+       ((caps->supported_prim_modes & caps->supported_restart_modes & BITFIELD_MASK(PIPE_PRIM_MAX))) !=
+                                      BITFIELD_MASK(PIPE_PRIM_MAX)) {
       struct primconvert_config cfg;
       cfg.fixed_prim_restart = caps->rewrite_restart_index;
       cfg.primtypes_mask = caps->supported_prim_modes;
-      cfg.restart_primtypes_mask = 0xff;
+      cfg.restart_primtypes_mask = caps->supported_restart_modes;
       mgr->pc = util_primconvert_create_config(pipe, &cfg);
    }
    mgr->translate_cache = translate_cache_create();
@@ -1392,6 +1395,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
        (!info->primitive_restart ||
         info->restart_index == fixed_restart_index ||
         !mgr->caps.rewrite_restart_index) &&
+       (!info->primitive_restart || mgr->caps.supported_restart_modes & BITFIELD_BIT(info->mode)) &&
        mgr->caps.supported_prim_modes & BITFIELD_BIT(info->mode)) {
 
       /* Set vertex buffers if needed. */
@@ -1673,7 +1677,8 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
 
    if ((new_info.index_size == 1 && mgr->caps.rewrite_ubyte_ibs) ||
        (new_info.primitive_restart &&
-        new_info.restart_index != fixed_restart_index && mgr->caps.rewrite_restart_index) ||
+        ((new_info.restart_index != fixed_restart_index && mgr->caps.rewrite_restart_index) ||
+        !(mgr->caps.supported_restart_modes & BITFIELD_BIT(new_info.mode)))) ||
        !(mgr->caps.supported_prim_modes & BITFIELD_BIT(new_info.mode))) {
       util_primconvert_save_flatshade_first(mgr->pc, mgr->flatshade_first);
       util_primconvert_draw_vbo(mgr->pc, &new_info, drawid_offset, indirect, &new_draw, 1);
index 486cd5d..5cefac5 100644 (file)
@@ -57,6 +57,7 @@ struct u_vbuf_caps {
    /* Maximum number of vertex buffers */
    unsigned max_vertex_buffers:6;
 
+   uint16_t supported_restart_modes;
    uint16_t supported_prim_modes;
    bool fallback_always;
    bool fallback_only_for_user_vbuffers;
index 8f5d2eb..cd5c50f 100644 (file)
@@ -105,6 +105,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    /* nv35 capabilities */
    case PIPE_CAP_DEPTH_BOUNDS_TEST:
       return eng3d->oclass == NV35_3D_CLASS || eng3d->oclass >= NV40_3D_CLASS;
+   case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART:
    case PIPE_CAP_SUPPORTED_PRIM_MODES:
       return BITFIELD_MASK(PIPE_PRIM_MAX);
    /* nv4x capabilities */
@@ -208,7 +209,6 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
    case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
    case PIPE_CAP_CULL_DISTANCE:
-   case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
    case PIPE_CAP_TGSI_VOTE:
    case PIPE_CAP_MAX_WINDOW_RECTANGLES:
    case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
index 92343e5..b2a0b16 100644 (file)
@@ -188,6 +188,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_MAX_TEXTURE_MB:
       return 0; /* TODO: use 1/2 of VRAM for this? */
 
+   case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART:
    case PIPE_CAP_SUPPORTED_PRIM_MODES:
       return BITFIELD_MASK(PIPE_PRIM_MAX);
 
@@ -316,7 +317,6 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_PCI_DEVICE:
    case PIPE_CAP_PCI_FUNCTION:
    case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
-   case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
    case PIPE_CAP_TGSI_VOTE:
    case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
    case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
index 6cd4aab..de6dd2b 100644 (file)
@@ -208,6 +208,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_MAX_TEXTURE_MB:
       return 0; /* TODO: use 1/2 of VRAM for this? */
 
+   case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART:
    case PIPE_CAP_SUPPORTED_PRIM_MODES:
       return BITFIELD_MASK(PIPE_PRIM_MAX);
 
@@ -283,7 +284,6 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_STRING_MARKER:
    case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
    case PIPE_CAP_CULL_DISTANCE:
-   case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
    case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
    case PIPE_CAP_TGSI_VOTE:
    case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
index 2e683d9..09db0b8 100644 (file)
@@ -869,7 +869,6 @@ enum pipe_cap
    PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT,
    PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR,
    PIPE_CAP_CULL_DISTANCE,
-   PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES,
    PIPE_CAP_TGSI_VOTE,
    PIPE_CAP_MAX_WINDOW_RECTANGLES,
    PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED,
@@ -991,6 +990,7 @@ enum pipe_cap
    PIPE_CAP_ALLOW_DYNAMIC_VAO_FASTPATH,
    PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART,
    PIPE_CAP_SUPPORTED_PRIM_MODES,
+   PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART,
 
    PIPE_CAP_LAST,
    /* XXX do not add caps after PIPE_CAP_LAST! */
index 18131af..075bb28 100644 (file)
@@ -410,8 +410,7 @@ void st_init_limits(struct pipe_screen *screen,
       !screen->get_param(screen, PIPE_CAP_NIR_COMPACT_ARRAYS);
    c->LowerCsDerivedVariables =
       !screen->get_param(screen, PIPE_CAP_CS_DERIVED_SYSTEM_VALUES_SUPPORTED);
-   c->PrimitiveRestartForPatches =
-      screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES);
+   c->PrimitiveRestartForPatches = false;
 
    c->MaxCombinedTextureImageUnits =
          _min(c->Program[MESA_SHADER_VERTEX].MaxTextureImageUnits +