Mesa (main): gallium: add a pipe cap to rewrite index buffers for draws using a non-fixed restart index
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Jun 23 03:52:35 UTC 2021
Module: Mesa
Branch: main
Commit: c9a65e5f77ef7c4ff72591ef1a8a57678eb8dda4
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=c9a65e5f77ef7c4ff72591ef1a8a57678eb8dda4
Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date: Fri May 21 07:00:52 2021 -0400
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 at amd.com>
Reviewed-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10973>
---
docs/gallium/screen.rst | 1 +
src/gallium/auxiliary/util/u_screen.c | 3 +++
src/gallium/auxiliary/util/u_vbuf.c | 32 ++++++++++++++++++++++++--
src/gallium/auxiliary/util/u_vbuf.h | 1 +
src/gallium/drivers/nouveau/nv30/nv30_screen.c | 1 +
src/gallium/drivers/nouveau/nv50/nv50_screen.c | 1 +
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 1 +
src/gallium/include/pipe/p_defines.h | 1 +
8 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/docs/gallium/screen.rst b/docs/gallium/screen.rst
index 328b3e3e2f2..4714c0417f5 100644
--- a/docs/gallium/screen.rst
+++ b/docs/gallium/screen.rst
@@ -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:
diff --git a/src/gallium/auxiliary/util/u_screen.c b/src/gallium/auxiliary/util/u_screen.c
index 32a35c1a8e9..f185282a961 100644
--- a/src/gallium/auxiliary/util/u_screen.c
+++ b/src/gallium/auxiliary/util/u_screen.c
@@ -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_*");
}
diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c
index 9e5f2e2366e..2d00c16c5e9 100644
--- a/src/gallium/auxiliary/util/u_vbuf.c
+++ b/src/gallium/auxiliary/util/u_vbuf.c
@@ -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);
diff --git a/src/gallium/auxiliary/util/u_vbuf.h b/src/gallium/auxiliary/util/u_vbuf.h
index 3ec93e662a7..a7360be3fc9 100644
--- a/src/gallium/auxiliary/util/u_vbuf.h
+++ b/src/gallium/auxiliary/util/u_vbuf.h
@@ -59,6 +59,7 @@ struct u_vbuf_caps {
bool fallback_always;
bool fallback_only_for_user_vbuffers;
+ bool rewrite_restart_index;
};
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
index cc2859384f7..45a75ebdd0e 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
@@ -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:
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
index cd9946baed6..c88942765f6 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
@@ -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:
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index d1e901c4820..84cae860ba6 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -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:
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 4523c405555..4747ef7953a 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -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! */
More information about the mesa-commit
mailing list