summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2016-06-04 14:13:38 -0400
committerEmil Velikov <[email protected]>2016-06-14 15:48:37 +0100
commitceb9ed0e386223711fe80d38daf0fbf64b6ced02 (patch)
tree43f29046366601ec622760628d417511f995ba18
parent5a63ae9f15523f58d8a82f5dc9fca89138aa92d0 (diff)
nvc0: reduce overhead from always marking images dirty
We would revalidate images when anything was touched at all. Which is unfortunate, since the state tracker does not use CSO's to reduce the workload. So instead implement a protocol to ensure that something has changed before revalidating all the images. Signed-off-by: Ilia Mirkin <[email protected]> Cc: "12.0" <[email protected]> (cherry picked from commit fd6bbc2ee205ed02f66a8d8ef5b2adf4005d588c)
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_state.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
index 6cdc007a086..92161ec9e65 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
@@ -1231,36 +1231,60 @@ nvc0_set_compute_resources(struct pipe_context *pipe,
nvc0_context(pipe)->dirty_cp |= NVC0_NEW_CP_SURFACES;
}
-static void
+static bool
nvc0_bind_images_range(struct nvc0_context *nvc0, const unsigned s,
unsigned start, unsigned nr,
struct pipe_image_view *pimages)
{
const unsigned end = start + nr;
- const unsigned mask = ((1 << nr) - 1) << start;
+ unsigned mask = 0;
unsigned i;
assert(s < 6);
if (pimages) {
for (i = start; i < end; ++i) {
+ struct pipe_image_view *img = &nvc0->images[s][i];
const unsigned p = i - start;
+
+ if (img->resource == pimages[p].resource &&
+ img->format == pimages[p].format &&
+ img->access == pimages[p].access) {
+ if (img->resource == NULL)
+ continue;
+ if (img->resource->target == PIPE_BUFFER &&
+ img->u.buf.first_element == pimages[p].u.buf.first_element &&
+ img->u.buf.last_element == pimages[p].u.buf.last_element)
+ continue;
+ if (img->resource->target != PIPE_BUFFER &&
+ img->u.tex.first_layer == pimages[p].u.tex.first_layer &&
+ img->u.tex.last_layer == pimages[p].u.tex.last_layer &&
+ img->u.tex.level == pimages[p].u.tex.level)
+ continue;
+ }
+
+ mask |= (1 << i);
if (pimages[p].resource)
nvc0->images_valid[s] |= (1 << i);
else
nvc0->images_valid[s] &= ~(1 << i);
- nvc0->images[s][i].format = pimages[p].format;
- nvc0->images[s][i].access = pimages[p].access;
- if (pimages[p].resource->target == PIPE_BUFFER)
- nvc0->images[s][i].u.buf = pimages[p].u.buf;
+ img->format = pimages[p].format;
+ img->access = pimages[p].access;
+ if (pimages[p].resource && pimages[p].resource->target == PIPE_BUFFER)
+ img->u.buf = pimages[p].u.buf;
else
- nvc0->images[s][i].u.tex = pimages[p].u.tex;
+ img->u.tex = pimages[p].u.tex;
pipe_resource_reference(
- &nvc0->images[s][i].resource, pimages[p].resource);
+ &img->resource, pimages[p].resource);
}
+ if (!mask)
+ return false;
} else {
+ mask = ((1 << nr) - 1) << start;
+ if (!(nvc0->images_valid[s] & mask))
+ return false;
for (i = start; i < end; ++i)
pipe_resource_reference(&nvc0->images[s][i].resource, NULL);
nvc0->images_valid[s] &= ~mask;
@@ -1271,6 +1295,8 @@ nvc0_bind_images_range(struct nvc0_context *nvc0, const unsigned s,
nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF);
else
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_SUF);
+
+ return true;
}
static void
@@ -1279,7 +1305,8 @@ nvc0_set_shader_images(struct pipe_context *pipe, unsigned shader,
struct pipe_image_view *images)
{
const unsigned s = nvc0_shader_stage(shader);
- nvc0_bind_images_range(nvc0_context(pipe), s, start, nr, images);
+ if (!nvc0_bind_images_range(nvc0_context(pipe), s, start, nr, images))
+ return;
if (s == 5)
nvc0_context(pipe)->dirty_cp |= NVC0_NEW_CP_SURFACES;