diff --git a/docs/gallium/screen.rst b/docs/gallium/screen.rst index 4714c0417f5..19dd2948bb2 100644 --- a/docs/gallium/screen.rst +++ b/docs/gallium/screen.rst @@ -616,6 +616,7 @@ The integer capabilities: * ``PIPE_CAP_SAMPLER_REDUCTION_MINMAX``: Driver supports EXT min/max sampler reduction. * ``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_capf: diff --git a/src/gallium/auxiliary/util/u_screen.c b/src/gallium/auxiliary/util/u_screen.c index f185282a961..70ac8a94aad 100644 --- a/src/gallium/auxiliary/util/u_screen.c +++ b/src/gallium/auxiliary/util/u_screen.c @@ -87,6 +87,9 @@ 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: + return BITFIELD_MASK(PIPE_PRIM_MAX); + case PIPE_CAP_MIN_TEXEL_OFFSET: /* GL 3.x minimum value. */ return -8; diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c index afb6db5c668..c09f785d3ae 100644 --- a/src/gallium/auxiliary/util/u_vbuf.c +++ b/src/gallium/auxiliary/util/u_vbuf.c @@ -310,6 +310,9 @@ void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps, caps->rewrite_restart_index = screen->get_param(screen, PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART); caps->fallback_always |= caps->rewrite_restart_index; } + caps->supported_prim_modes = screen->get_param(screen, PIPE_CAP_SUPPORTED_PRIM_MODES); + if (caps->supported_prim_modes != BITFIELD_MASK(PIPE_PRIM_MAX)) + caps->fallback_always = true; if (!screen->is_format_supported(screen, PIPE_FORMAT_R8_UINT, PIPE_BUFFER, 0, 0, PIPE_BIND_INDEX_BUFFER)) caps->fallback_always = caps->rewrite_ubyte_ibs = true; @@ -334,10 +337,11 @@ 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) { + if (caps->rewrite_ubyte_ibs || caps->rewrite_restart_index || + (caps->supported_prim_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 = 0xff; + cfg.primtypes_mask = caps->supported_prim_modes; cfg.restart_primtypes_mask = 0xff; mgr->pc = util_primconvert_create_config(pipe, &cfg); } @@ -1387,7 +1391,8 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info, (info->index_size != 1 || !mgr->caps.rewrite_ubyte_ibs) && (!info->primitive_restart || info->restart_index == fixed_restart_index || - !mgr->caps.rewrite_restart_index)) { + !mgr->caps.rewrite_restart_index) && + mgr->caps.supported_prim_modes & BITFIELD_BIT(info->mode)) { /* Set vertex buffers if needed. */ if (mgr->dirty_real_vb_mask & used_vb_mask) { @@ -1668,7 +1673,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_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); } else diff --git a/src/gallium/auxiliary/util/u_vbuf.h b/src/gallium/auxiliary/util/u_vbuf.h index b4a96dc38ce..486cd5d2f3d 100644 --- a/src/gallium/auxiliary/util/u_vbuf.h +++ b/src/gallium/auxiliary/util/u_vbuf.h @@ -57,6 +57,7 @@ struct u_vbuf_caps { /* Maximum number of vertex buffers */ unsigned max_vertex_buffers:6; + uint16_t supported_prim_modes; bool fallback_always; bool fallback_only_for_user_vbuffers; bool rewrite_ubyte_ibs; diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c index 45a75ebdd0e..8f5d2eb1b7a 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c @@ -105,6 +105,8 @@ 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: + return BITFIELD_MASK(PIPE_PRIM_MAX); /* nv4x capabilities */ case PIPE_CAP_BLEND_EQUATION_SEPARATE: case PIPE_CAP_NPOT_TEXTURES: diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c index c88942765f6..92343e54346 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -188,6 +188,9 @@ 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: + return BITFIELD_MASK(PIPE_PRIM_MAX); + /* supported caps */ case PIPE_CAP_TEXTURE_MIRROR_CLAMP: case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE: diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index 84cae860ba6..6cd4aab1f09 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -208,6 +208,9 @@ 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: + return BITFIELD_MASK(PIPE_PRIM_MAX); + /* supported caps */ case PIPE_CAP_TEXTURE_MIRROR_CLAMP: case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE: diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 4747ef7953a..2e683d989f4 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -990,6 +990,7 @@ enum pipe_cap PIPE_CAP_SAMPLER_REDUCTION_MINMAX_ARB, PIPE_CAP_ALLOW_DYNAMIC_VAO_FASTPATH, PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART, + PIPE_CAP_SUPPORTED_PRIM_MODES, PIPE_CAP_LAST, /* XXX do not add caps after PIPE_CAP_LAST! */