summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe/lp_state_sampler.c
diff options
context:
space:
mode:
authorRoland Scheidegger <[email protected]>2016-01-15 03:10:40 +0100
committerRoland Scheidegger <[email protected]>2016-01-15 20:13:45 +0100
commit03f66dfb4b399f078fc1bc99be1f0937ce981def (patch)
treeea4e10dd8dea6dae5b1ae78b63089cf438e525cc /src/gallium/drivers/llvmpipe/lp_state_sampler.c
parent2f9a325b6ac1609a9986b4bee161610730da7da5 (diff)
llvmpipe: ditch additional ref counting for vertex/geometry sampler views
The cleaning up was quite a performance hog (making pipe_resource_reference the number two in profilers on the vertex path, and 3rd overall, with its cousin pipe_reference_described not far behind) if there were lots of tiny draw calls (ipers). Now the reason was really that it was blindly calling this for all potential shader views (so 32 each for vs and gs) even though the app never touched a single one which could have been fixed, however I can't come up with a good reason why we refcount these. We've got references, of course, in the sampler views, which should be quite sufficient as we do all vertex and geometry shader execution fully synchronous. (Calling prepare_shader_sampling for all draw calls even if there were no changes looks quite suboptimal too, but generally we don't really expect vs/gs shader sampling to be used much with llvmpipe, and there's even an early exit if there aren't any views to avoid the "null loop" albeit it's now no longer always trying to loop through all 32 slots. Maybe improve another time...). Of course, if we manage to make vertex loads run asynchronously some day, we need references again, but adding that back would be the least of the problems... Also only set LP_NEW_SAMPLER_VIEW for fragment sampler views. Nothing on the vertex side depends on it (I suppose we'd really wanted a separate flag in any case). (Good for a 3% improvement or so in ipers under the right conditions.) Reviewed-by: Jose Fonseca <[email protected]>
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_state_sampler.c')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_sampler.c47
1 files changed, 12 insertions, 35 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
index 1e055878f7c..69af38e92c0 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
@@ -98,8 +98,9 @@ llvmpipe_bind_sampler_states(struct pipe_context *pipe,
llvmpipe->samplers[shader],
llvmpipe->num_samplers[shader]);
}
-
- llvmpipe->dirty |= LP_NEW_SAMPLER;
+ else {
+ llvmpipe->dirty |= LP_NEW_SAMPLER;
+ }
}
@@ -146,8 +147,9 @@ llvmpipe_set_sampler_views(struct pipe_context *pipe,
llvmpipe->sampler_views[shader],
llvmpipe->num_sampler_views[shader]);
}
-
- llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;
+ else {
+ llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;
+ }
}
@@ -228,8 +230,7 @@ prepare_shader_sampling(
struct llvmpipe_context *lp,
unsigned num,
struct pipe_sampler_view **views,
- unsigned shader_type,
- struct pipe_resource *mapped_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS])
+ unsigned shader_type)
{
unsigned i;
@@ -242,7 +243,7 @@ prepare_shader_sampling(
if (!num)
return;
- for (i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) {
+ for (i = 0; i < num; i++) {
struct pipe_sampler_view *view = i < num ? views[i] : NULL;
if (view) {
@@ -253,11 +254,6 @@ prepare_shader_sampling(
unsigned first_level = 0;
unsigned last_level = 0;
- /* We're referencing the texture's internal data, so save a
- * reference to it.
- */
- pipe_resource_reference(&mapped_tex[i], tex);
-
if (!lp_tex->dt) {
/* regular texture - setup array of mipmap level offsets */
struct pipe_resource *res = view->texture;
@@ -335,47 +331,28 @@ prepare_shader_sampling(
/**
- * Called during state validation when LP_NEW_SAMPLER_VIEW is set.
+ * Called whenever we're about to draw (no dirty flag, FIXME?).
*/
void
llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
unsigned num,
struct pipe_sampler_view **views)
{
- prepare_shader_sampling(lp, num, views, PIPE_SHADER_VERTEX,
- lp->mapped_vs_tex);
-}
-
-void
-llvmpipe_cleanup_vertex_sampling(struct llvmpipe_context *ctx)
-{
- unsigned i;
- for (i = 0; i < Elements(ctx->mapped_vs_tex); i++) {
- pipe_resource_reference(&ctx->mapped_vs_tex[i], NULL);
- }
+ prepare_shader_sampling(lp, num, views, PIPE_SHADER_VERTEX);
}
/**
- * Called during state validation when LP_NEW_SAMPLER_VIEW is set.
+ * Called whenever we're about to draw (no dirty flag, FIXME?).
*/
void
llvmpipe_prepare_geometry_sampling(struct llvmpipe_context *lp,
unsigned num,
struct pipe_sampler_view **views)
{
- prepare_shader_sampling(lp, num, views, PIPE_SHADER_GEOMETRY,
- lp->mapped_gs_tex);
+ prepare_shader_sampling(lp, num, views, PIPE_SHADER_GEOMETRY);
}
-void
-llvmpipe_cleanup_geometry_sampling(struct llvmpipe_context *ctx)
-{
- unsigned i;
- for (i = 0; i < Elements(ctx->mapped_gs_tex); i++) {
- pipe_resource_reference(&ctx->mapped_gs_tex[i], NULL);
- }
-}
void
llvmpipe_init_sampler_funcs(struct llvmpipe_context *llvmpipe)