aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/cso_cache
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2019-12-29 23:00:53 -0500
committerMarek Olšák <[email protected]>2020-01-08 13:40:59 -0500
commiteb1e10d0be90c7aee9d88c1a18be803a643715dc (patch)
tree71bedf5e2698d6ddc53aa1395b656c556328787d /src/gallium/auxiliary/cso_cache
parent9f6020abc6beaab9c8f43f483ef84b54c28e50a2 (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.c81
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.h9
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 */