gallium: add a pipe cap to rewrite index buffers for draws using a non-fixed restart index

for drivers that set it, this now automatically handles restart index rewriting
by running draws through primconvert when necessary

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>
This commit is contained in:
Mike Blumenkrantz
2021-05-21 07:00:52 -04:00
committed by Marge Bot
parent 99a60ed378
commit c9a65e5f77
8 changed files with 39 additions and 2 deletions

View File

@@ -615,6 +615,7 @@ The integer capabilities:
* ``PIPE_CAP_TEXRECT``: Driver supports rectangle textures. Required for OpenGL on `!prefers_nir` drivers. If this cap is not present, st/mesa will lower the NIR to use normal 2D texture sampling by using either `txs` or `nir_intrinsic_load_texture_scaling` to normalize the texture coordinates.
* ``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_capf:

View File

@@ -466,6 +466,9 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen,
case PIPE_CAP_ALLOW_DYNAMIC_VAO_FASTPATH:
return 1;
case PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART:
return 0;
default:
unreachable("bad PIPE_CAP_*");
}

View File

@@ -91,6 +91,8 @@
#include "util/format/u_format.h"
#include "util/u_inlines.h"
#include "util/u_memory.h"
#include "indices/u_primconvert.h"
#include "util/u_prim_restart.h"
#include "util/u_screen.h"
#include "util/u_upload_mgr.h"
#include "translate/translate.h"
@@ -152,6 +154,7 @@ struct u_vbuf {
struct translate_cache *translate_cache;
struct cso_cache cso_cache;
struct primconvert_context *pc;
bool flatshade_first;
/* This is what was set in set_vertex_buffers.
@@ -302,6 +305,12 @@ void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps,
caps->max_vertex_buffers =
screen->get_param(screen, PIPE_CAP_MAX_VERTEX_BUFFERS);
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->fallback_always |= caps->rewrite_restart_index;
}
/* OpenGL 2.0 requires a minimum of 16 vertex buffers */
if (caps->max_vertex_buffers < 16)
caps->fallback_always = true;
@@ -322,6 +331,13 @@ u_vbuf_create(struct pipe_context *pipe, struct u_vbuf_caps *caps)
mgr->caps = *caps;
mgr->pipe = pipe;
if (caps->rewrite_restart_index) {
struct primconvert_config cfg;
cfg.fixed_prim_restart = caps->rewrite_restart_index;
cfg.primtypes_mask = 0xff;
cfg.restart_primtypes_mask = 0xff;
mgr->pc = util_primconvert_create_config(pipe, &cfg);
}
mgr->translate_cache = translate_cache_create();
memset(mgr->fallback_vbs, ~0, sizeof(mgr->fallback_vbs));
mgr->allowed_vb_mask = u_bit_consecutive(0, mgr->caps.max_vertex_buffers);
@@ -405,6 +421,9 @@ void u_vbuf_destroy(struct u_vbuf *mgr)
for (i = 0; i < PIPE_MAX_ATTRIBS; i++)
pipe_vertex_buffer_unreference(&mgr->real_vertex_buffer[i]);
if (mgr->pc)
util_primconvert_destroy(mgr->pc);
translate_cache_destroy(mgr->translate_cache);
cso_cache_delete(&mgr->cso_cache);
FREE(mgr);
@@ -1356,11 +1375,15 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
mgr->incompatible_vb_mask & used_vb_mask;
struct pipe_draw_info new_info;
struct pipe_draw_start_count_bias new_draw;
unsigned fixed_restart_index = info->index_size ? util_prim_restart_index_from_size(info->index_size) : 0;
/* Normal draw. No fallback and no user buffers. */
if (!incompatible_vb_mask &&
!mgr->ve->incompatible_elem_mask &&
!user_vb_mask) {
!user_vb_mask &&
(!info->primitive_restart ||
info->restart_index == fixed_restart_index ||
!mgr->caps.rewrite_restart_index)) {
/* Set vertex buffers if needed. */
if (mgr->dirty_real_vb_mask & used_vb_mask) {
@@ -1639,7 +1662,12 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
if (mgr->dirty_real_vb_mask)
u_vbuf_set_driver_vertex_buffers(mgr);
pipe->draw_vbo(pipe, &new_info, drawid_offset, indirect, &new_draw, 1);
if (new_info.primitive_restart &&
(new_info.restart_index != fixed_restart_index && mgr->caps.rewrite_restart_index)) {
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
pipe->draw_vbo(pipe, &new_info, drawid_offset, indirect, &new_draw, 1);
if (mgr->using_translate) {
u_vbuf_translate_end(mgr);

View File

@@ -59,6 +59,7 @@ struct u_vbuf_caps {
bool fallback_always;
bool fallback_only_for_user_vbuffers;
bool rewrite_restart_index;
};

View File

@@ -115,6 +115,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:
return (eng3d->oclass >= NV40_3D_CLASS) ? 1 : 0;
/* unsupported */
case PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART:
case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:

View File

@@ -275,6 +275,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return class_3d >= NVA3_3D_CLASS;
/* unsupported caps */
case PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART:
case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:

View File

@@ -350,6 +350,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return 0;
/* unsupported caps */
case PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART:
case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:

View File

@@ -989,6 +989,7 @@ enum pipe_cap
PIPE_CAP_SAMPLER_REDUCTION_MINMAX,
PIPE_CAP_SAMPLER_REDUCTION_MINMAX_ARB,
PIPE_CAP_ALLOW_DYNAMIC_VAO_FASTPATH,
PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART,
PIPE_CAP_LAST,
/* XXX do not add caps after PIPE_CAP_LAST! */