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:

committed by
Marge Bot

parent
99a60ed378
commit
c9a65e5f77
@@ -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:
|
||||
|
||||
|
@@ -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_*");
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -59,6 +59,7 @@ struct u_vbuf_caps {
|
||||
|
||||
bool fallback_always;
|
||||
bool fallback_only_for_user_vbuffers;
|
||||
bool rewrite_restart_index;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -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:
|
||||
|
@@ -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:
|
||||
|
@@ -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:
|
||||
|
@@ -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! */
|
||||
|
Reference in New Issue
Block a user