mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 02:48:06 +02:00
cso: remove cso_draw_vbo from all draws, call the driver or u_vbuf directly
Instead of calling like this:
st_draw_gallium -> cso_draw_vbo -> driver_draw_vbo
Do it like this:
st_draw_gallium -> driver_draw_vbo
OR
st_draw_gallium -> u_vbuf_draw_vbo
It's accomplished by adding a draw_vbo function pointer into cso_context.
The pointer is equal to pipe_context::draw_vbo when needed, so there is
no call overhead from this if cso's draw_vbo callback is indeed equal to
driver_draw_vbo. We just call cso_context_base::draw_vbo to jump into
the driver directly, or u_vbuf if needed.
The cso function with the indirect function call is inlined, so draws
don't actually visit any cso_context function.
Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20025>
This commit is contained in:
parent
85f01982a0
commit
c9b13a9338
2 changed files with 70 additions and 41 deletions
|
|
@ -50,6 +50,7 @@
|
||||||
#include "cso_cache/cso_hash.h"
|
#include "cso_cache/cso_hash.h"
|
||||||
#include "cso_context.h"
|
#include "cso_context.h"
|
||||||
#include "driver_trace/tr_dump.h"
|
#include "driver_trace/tr_dump.h"
|
||||||
|
#include "util/u_threaded_context.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Per-shader sampler information.
|
* Per-shader sampler information.
|
||||||
|
|
@ -260,6 +261,19 @@ cso_init_vbuf(struct cso_context *cso, unsigned flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cso_draw_vbo_default(struct pipe_context *pipe,
|
||||||
|
const struct pipe_draw_info *info,
|
||||||
|
unsigned drawid_offset,
|
||||||
|
const struct pipe_draw_indirect_info *indirect,
|
||||||
|
const struct pipe_draw_start_count_bias *draws,
|
||||||
|
unsigned num_draws)
|
||||||
|
{
|
||||||
|
if (pipe->vbuf)
|
||||||
|
u_vbuf_draw_vbo(pipe, info, drawid_offset, indirect, draws, num_draws);
|
||||||
|
else
|
||||||
|
pipe->draw_vbo(pipe, info, drawid_offset, indirect, draws, num_draws);
|
||||||
|
}
|
||||||
|
|
||||||
struct cso_context *
|
struct cso_context *
|
||||||
cso_create_context(struct pipe_context *pipe, unsigned flags)
|
cso_create_context(struct pipe_context *pipe, unsigned flags)
|
||||||
|
|
@ -277,6 +291,21 @@ cso_create_context(struct pipe_context *pipe, unsigned flags)
|
||||||
if (!(flags & CSO_NO_VBUF))
|
if (!(flags & CSO_NO_VBUF))
|
||||||
cso_init_vbuf(ctx, flags);
|
cso_init_vbuf(ctx, flags);
|
||||||
|
|
||||||
|
/* Only drivers using u_threaded_context benefit from the direct call.
|
||||||
|
* This is because drivers can change draw_vbo, but u_threaded_context
|
||||||
|
* never changes it.
|
||||||
|
*/
|
||||||
|
if (pipe->draw_vbo == tc_draw_vbo) {
|
||||||
|
if (ctx->vbuf_current)
|
||||||
|
ctx->base.draw_vbo = u_vbuf_draw_vbo;
|
||||||
|
else
|
||||||
|
ctx->base.draw_vbo = pipe->draw_vbo;
|
||||||
|
} else if (ctx->always_use_vbuf) {
|
||||||
|
ctx->base.draw_vbo = u_vbuf_draw_vbo;
|
||||||
|
} else {
|
||||||
|
ctx->base.draw_vbo = cso_draw_vbo_default;
|
||||||
|
}
|
||||||
|
|
||||||
/* Enable for testing: */
|
/* Enable for testing: */
|
||||||
if (0) cso_set_maximum_cache_size(&ctx->cache, 4);
|
if (0) cso_set_maximum_cache_size(&ctx->cache, 4);
|
||||||
|
|
||||||
|
|
@ -1268,7 +1297,9 @@ cso_set_vertex_buffers_and_elements(struct cso_context *ctx,
|
||||||
|
|
||||||
/* Unset this to make sure the CSO is re-bound on the next use. */
|
/* Unset this to make sure the CSO is re-bound on the next use. */
|
||||||
ctx->velements = NULL;
|
ctx->velements = NULL;
|
||||||
ctx->vbuf_current = vbuf;
|
ctx->vbuf_current = pipe->vbuf = vbuf;
|
||||||
|
if (pipe->draw_vbo == tc_draw_vbo)
|
||||||
|
ctx->base.draw_vbo = u_vbuf_draw_vbo;
|
||||||
unbind_trailing_vb_count = 0;
|
unbind_trailing_vb_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1289,7 +1320,9 @@ cso_set_vertex_buffers_and_elements(struct cso_context *ctx,
|
||||||
|
|
||||||
/* Unset this to make sure the CSO is re-bound on the next use. */
|
/* Unset this to make sure the CSO is re-bound on the next use. */
|
||||||
u_vbuf_unset_vertex_elements(vbuf);
|
u_vbuf_unset_vertex_elements(vbuf);
|
||||||
ctx->vbuf_current = NULL;
|
ctx->vbuf_current = pipe->vbuf = NULL;
|
||||||
|
if (pipe->draw_vbo == tc_draw_vbo)
|
||||||
|
ctx->base.draw_vbo = pipe->draw_vbo;
|
||||||
unbind_trailing_vb_count = 0;
|
unbind_trailing_vb_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1732,37 +1765,6 @@ cso_restore_compute_state(struct cso_context *cso)
|
||||||
|
|
||||||
/* drawing */
|
/* drawing */
|
||||||
|
|
||||||
void
|
|
||||||
cso_draw_vbo(struct cso_context *cso,
|
|
||||||
struct pipe_draw_info *info,
|
|
||||||
unsigned drawid_offset,
|
|
||||||
const struct pipe_draw_indirect_info *indirect,
|
|
||||||
const struct pipe_draw_start_count_bias *draws,
|
|
||||||
unsigned num_draws)
|
|
||||||
{
|
|
||||||
/* We can't have both indirect drawing and SO-vertex-count drawing */
|
|
||||||
assert(!indirect ||
|
|
||||||
indirect->buffer == NULL ||
|
|
||||||
indirect->count_from_stream_output == NULL);
|
|
||||||
|
|
||||||
/* We can't have SO-vertex-count drawing with an index buffer */
|
|
||||||
assert(info->index_size == 0 ||
|
|
||||||
!indirect ||
|
|
||||||
indirect->count_from_stream_output == NULL);
|
|
||||||
|
|
||||||
/* Indirect only uses indirect->draw_count, not num_draws. */
|
|
||||||
assert(!indirect || num_draws == 1);
|
|
||||||
|
|
||||||
struct pipe_context *pipe = cso->base.pipe;
|
|
||||||
|
|
||||||
if (cso->vbuf_current) {
|
|
||||||
u_vbuf_draw_vbo(pipe, info, drawid_offset, indirect, draws, num_draws);
|
|
||||||
} else {
|
|
||||||
pipe->draw_vbo(pipe, info, drawid_offset, indirect, draws, num_draws);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cso_draw_arrays(struct cso_context *cso, uint mode, uint start, uint count)
|
cso_draw_arrays(struct cso_context *cso, uint mode, uint start, uint count)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,14 @@ struct u_vbuf;
|
||||||
|
|
||||||
struct cso_context_base {
|
struct cso_context_base {
|
||||||
struct pipe_context *pipe;
|
struct pipe_context *pipe;
|
||||||
|
|
||||||
|
/* This is equal to either pipe_context::draw_vbo or u_vbuf_draw_vbo. */
|
||||||
|
void (*draw_vbo)(struct pipe_context *pipe,
|
||||||
|
const struct pipe_draw_info *info,
|
||||||
|
unsigned drawid_offset,
|
||||||
|
const struct pipe_draw_indirect_info *indirect,
|
||||||
|
const struct pipe_draw_start_count_bias *draws,
|
||||||
|
unsigned num_draws);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CSO_NO_USER_VERTEX_BUFFERS (1 << 0)
|
#define CSO_NO_USER_VERTEX_BUFFERS (1 << 0)
|
||||||
|
|
@ -210,14 +218,6 @@ cso_set_vertex_buffers_and_elements(struct cso_context *ctx,
|
||||||
bool uses_user_vertex_buffers,
|
bool uses_user_vertex_buffers,
|
||||||
const struct pipe_vertex_buffer *vbuffers);
|
const struct pipe_vertex_buffer *vbuffers);
|
||||||
|
|
||||||
void
|
|
||||||
cso_draw_vbo(struct cso_context *cso,
|
|
||||||
struct pipe_draw_info *info,
|
|
||||||
unsigned drawid_offset,
|
|
||||||
const struct pipe_draw_indirect_info *indirect,
|
|
||||||
const struct pipe_draw_start_count_bias *draws,
|
|
||||||
unsigned num_draws);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cso_draw_arrays_instanced(struct cso_context *cso, uint mode,
|
cso_draw_arrays_instanced(struct cso_context *cso, uint mode,
|
||||||
uint start, uint count,
|
uint start, uint count,
|
||||||
|
|
@ -236,6 +236,33 @@ cso_get_pipe_context(struct cso_context *cso)
|
||||||
return cso_base->pipe;
|
return cso_base->pipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ALWAYS_INLINE void
|
||||||
|
cso_draw_vbo(struct cso_context *cso,
|
||||||
|
struct pipe_draw_info *info,
|
||||||
|
unsigned drawid_offset,
|
||||||
|
const struct pipe_draw_indirect_info *indirect,
|
||||||
|
const struct pipe_draw_start_count_bias *draws,
|
||||||
|
unsigned num_draws)
|
||||||
|
{
|
||||||
|
/* We can't have both indirect drawing and SO-vertex-count drawing */
|
||||||
|
assert(!indirect ||
|
||||||
|
indirect->buffer == NULL ||
|
||||||
|
indirect->count_from_stream_output == NULL);
|
||||||
|
|
||||||
|
/* We can't have SO-vertex-count drawing with an index buffer */
|
||||||
|
assert(info->index_size == 0 ||
|
||||||
|
!indirect ||
|
||||||
|
indirect->count_from_stream_output == NULL);
|
||||||
|
|
||||||
|
/* Indirect only uses indirect->draw_count, not num_draws. */
|
||||||
|
assert(!indirect || num_draws == 1);
|
||||||
|
|
||||||
|
struct cso_context_base *cso_base = (struct cso_context_base *)cso;
|
||||||
|
|
||||||
|
cso_base->draw_vbo(cso_base->pipe, info, drawid_offset, indirect, draws,
|
||||||
|
num_draws);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue