diff options
author | Marek Olšák <[email protected]> | 2019-12-29 23:00:53 -0500 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2020-01-08 13:40:59 -0500 |
commit | eb1e10d0be90c7aee9d88c1a18be803a643715dc (patch) | |
tree | 71bedf5e2698d6ddc53aa1395b656c556328787d /src/gallium/auxiliary/cso_cache | |
parent | 9f6020abc6beaab9c8f43f483ef84b54c28e50a2 (diff) |
gallium: bypass u_vbuf if it's not needed (no fallbacks and no user VBOs)
This decreases CPU overhead, because u_vbuf is completely bypassed
in those cases.
Acked-by: Alyssa Rosenzweig <[email protected]>
Diffstat (limited to 'src/gallium/auxiliary/cso_cache')
-rw-r--r-- | src/gallium/auxiliary/cso_cache/cso_context.c | 81 | ||||
-rw-r--r-- | src/gallium/auxiliary/cso_cache/cso_context.h | 9 |
2 files changed, 83 insertions, 7 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 3d730ab9404..d7c017a91f2 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -64,7 +64,10 @@ struct sampler_info struct cso_context { struct pipe_context *pipe; struct cso_cache *cache; + struct u_vbuf *vbuf; + struct u_vbuf *vbuf_current; + bool always_use_vbuf; boolean has_geometry_shader; boolean has_tessellation; @@ -296,6 +299,8 @@ static void cso_init_vbuf(struct cso_context *cso, unsigned flags) (uses_user_vertex_buffers && caps.fallback_only_for_user_vbuffers)) { cso->vbuf = u_vbuf_create(cso->pipe, &caps); + cso->vbuf_current = cso->vbuf; + cso->always_use_vbuf = caps.fallback_always; } } @@ -1112,7 +1117,7 @@ cso_set_vertex_elements(struct cso_context *ctx, unsigned count, const struct pipe_vertex_element *states) { - struct u_vbuf *vbuf = ctx->vbuf; + struct u_vbuf *vbuf = ctx->vbuf_current; if (vbuf) { u_vbuf_set_vertex_elements(vbuf, count, states); @@ -1126,7 +1131,7 @@ cso_set_vertex_elements(struct cso_context *ctx, static void cso_save_vertex_elements(struct cso_context *ctx) { - struct u_vbuf *vbuf = ctx->vbuf; + struct u_vbuf *vbuf = ctx->vbuf_current; if (vbuf) { u_vbuf_save_vertex_elements(vbuf); @@ -1140,7 +1145,7 @@ cso_save_vertex_elements(struct cso_context *ctx) static void cso_restore_vertex_elements(struct cso_context *ctx) { - struct u_vbuf *vbuf = ctx->vbuf; + struct u_vbuf *vbuf = ctx->vbuf_current; if (vbuf) { u_vbuf_restore_vertex_elements(vbuf); @@ -1181,7 +1186,7 @@ void cso_set_vertex_buffers(struct cso_context *ctx, unsigned start_slot, unsigned count, const struct pipe_vertex_buffer *buffers) { - struct u_vbuf *vbuf = ctx->vbuf; + struct u_vbuf *vbuf = ctx->vbuf_current; if (!count) return; @@ -1197,7 +1202,7 @@ void cso_set_vertex_buffers(struct cso_context *ctx, static void cso_save_vertex_buffer0(struct cso_context *ctx) { - struct u_vbuf *vbuf = ctx->vbuf; + struct u_vbuf *vbuf = ctx->vbuf_current; if (vbuf) { u_vbuf_save_vertex_buffer0(vbuf); @@ -1211,7 +1216,7 @@ cso_save_vertex_buffer0(struct cso_context *ctx) static void cso_restore_vertex_buffer0(struct cso_context *ctx) { - struct u_vbuf *vbuf = ctx->vbuf; + struct u_vbuf *vbuf = ctx->vbuf_current; if (vbuf) { u_vbuf_restore_vertex_buffer0(vbuf); @@ -1222,6 +1227,68 @@ cso_restore_vertex_buffer0(struct cso_context *ctx) pipe_vertex_buffer_unreference(&ctx->vertex_buffer0_saved); } +/** + * Set vertex buffers and vertex elements. Skip u_vbuf if it's only needed + * for user vertex buffers and user vertex buffers are not set by this call. + * u_vbuf will be disabled. To re-enable u_vbuf, call this function again. + * + * Skipping u_vbuf decreases CPU overhead for draw calls that don't need it, + * such as VBOs, glBegin/End, and display lists. + * + * Internal operations that do "save states, draw, restore states" shouldn't + * use this, because the states are only saved in either cso_context or + * u_vbuf, not both. + */ +void +cso_set_vertex_buffers_and_elements(struct cso_context *ctx, + unsigned velem_count, + const struct pipe_vertex_element *velems, + unsigned vb_count, + unsigned unbind_trailing_vb_count, + const struct pipe_vertex_buffer *vbuffers, + bool uses_user_vertex_buffers) +{ + struct u_vbuf *vbuf = ctx->vbuf; + + if (vbuf && (ctx->always_use_vbuf || uses_user_vertex_buffers)) { + if (!ctx->vbuf_current) { + /* Unbind all buffers in cso_context, because we'll use u_vbuf. */ + unsigned unbind_vb_count = vb_count + unbind_trailing_vb_count; + if (unbind_vb_count) + cso_set_vertex_buffers_direct(ctx, 0, unbind_vb_count, NULL); + + /* Unset this to make sure the CSO is re-bound on the next use. */ + ctx->velements = NULL; + ctx->vbuf_current = vbuf; + } else if (unbind_trailing_vb_count) { + u_vbuf_set_vertex_buffers(vbuf, vb_count, unbind_trailing_vb_count, + NULL); + } + + if (vb_count) + u_vbuf_set_vertex_buffers(vbuf, 0, vb_count, vbuffers); + u_vbuf_set_vertex_elements(vbuf, velem_count, velems); + return; + } + + if (ctx->vbuf_current) { + /* Unbind all buffers in u_vbuf, because we'll use cso_context. */ + unsigned unbind_vb_count = vb_count + unbind_trailing_vb_count; + if (unbind_vb_count) + u_vbuf_set_vertex_buffers(vbuf, 0, unbind_vb_count, NULL); + + /* Unset this to make sure the CSO is re-bound on the next use. */ + u_vbuf_unset_vertex_elements(vbuf); + ctx->vbuf_current = NULL; + } else if (unbind_trailing_vb_count) { + cso_set_vertex_buffers_direct(ctx, vb_count, unbind_trailing_vb_count, + NULL); + } + + if (vb_count) + cso_set_vertex_buffers_direct(ctx, 0, vb_count, vbuffers); + cso_set_vertex_elements_direct(ctx, velem_count, velems); +} void cso_single_sampler(struct cso_context *ctx, enum pipe_shader_type shader_stage, @@ -1717,7 +1784,7 @@ void cso_draw_vbo(struct cso_context *cso, const struct pipe_draw_info *info) { - struct u_vbuf *vbuf = cso->vbuf; + struct u_vbuf *vbuf = cso->vbuf_current; /* We can't have both indirect drawing and SO-vertex-count drawing */ assert(info->indirect == NULL || info->count_from_stream_output == NULL); diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index de8c60fd2c1..0204ace34b7 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -219,6 +219,15 @@ void cso_save_constant_buffer_slot0(struct cso_context *cso, void cso_restore_constant_buffer_slot0(struct cso_context *cso, enum pipe_shader_type shader_stage); +/* Optimized version. */ +void +cso_set_vertex_buffers_and_elements(struct cso_context *ctx, + unsigned velem_count, + const struct pipe_vertex_element *velems, + unsigned vb_count, + unsigned unbind_trailing_vb_count, + const struct pipe_vertex_buffer *vbuffers, + bool uses_user_vertex_buffers); /* drawing */ |