summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nouveau/nvc0
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2016-03-18 11:11:24 +0100
committerSamuel Pitoiset <[email protected]>2016-04-26 19:47:49 +0200
commitafa04785fade4ed032a621db13e0a03505afa7ee (patch)
tree8464dc82abc9e33c979ddd367db7215ebae315e0 /src/gallium/drivers/nouveau/nvc0
parentc62b1b92f7da2563511581a2a74048334585da27 (diff)
nvc0: add preliminary support for images
This implements set_shader_images() and resource invalidation for images. As OpenGL requires at least 8 images, we are going to expose this minimum value even if this might be raised for Kepler, but this limit is mainly for Fermi because the hardware only accepts 8 images. Based on original patch by Ilia Mirkin. Signed-off-by: Samuel Pitoiset <[email protected]> Reviewed-by: Ilia Mirkin <[email protected]>
Diffstat (limited to 'src/gallium/drivers/nouveau/nvc0')
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_context.c17
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_context.h4
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_screen.h1
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_state.c53
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c1
5 files changed, 74 insertions, 2 deletions
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
index fcb8289beda..9e8fd6bbb8d 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
@@ -301,6 +301,23 @@ nvc0_invalidate_resource_storage(struct nouveau_context *ctx,
}
}
}
+
+ for (s = 0; s < 6; ++s) {
+ for (i = 0; i < NVC0_MAX_IMAGES; ++i) {
+ if (nvc0->images[s][i].resource == res) {
+ nvc0->images_dirty[s] |= 1 << i;
+ if (unlikely(s == 5)) {
+ nvc0->dirty_cp |= NVC0_NEW_CP_SURFACES;
+ nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF);
+ } else {
+ nvc0->dirty_3d |= NVC0_NEW_3D_SURFACES;
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_SUF);
+ }
+ }
+ if (!--ref)
+ return ref;
+ }
+ }
}
return ref;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
index 91dffa116e1..617f4c2ecc3 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
@@ -237,6 +237,10 @@ struct nvc0_context {
uint32_t buffers_dirty[6];
uint32_t buffers_valid[6];
+ struct pipe_image_view images[6][NVC0_MAX_IMAGES];
+ uint16_t images_dirty[6];
+ uint16_t images_valid[6];
+
struct util_dynarray global_residents;
};
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
index 0f782207f13..750bba01e73 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
@@ -23,6 +23,7 @@
#define NVC0_MAX_BUFFERS 32
+#define NVC0_MAX_IMAGES 8
struct nvc0_context;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
index a100fc4c478..e437a6479a0 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
@@ -1232,10 +1232,59 @@ nvc0_set_compute_resources(struct pipe_context *pipe,
}
static void
+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 i;
+
+ assert(s < 6);
+
+ if (pimages) {
+ for (i = start; i < end; ++i) {
+ const unsigned p = i - start;
+ 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;
+ else
+ nvc0->images[s][i].u.tex = pimages[p].u.tex;
+
+ pipe_resource_reference(
+ &nvc0->images[s][i].resource, pimages[p].resource);
+ }
+ } else {
+ for (i = start; i < end; ++i)
+ pipe_resource_reference(&nvc0->images[s][i].resource, NULL);
+ nvc0->images_valid[s] &= ~mask;
+ }
+ nvc0->images_dirty[s] |= mask;
+
+ if (s == 5)
+ nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF);
+ else
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_SUF);
+}
+
+static void
nvc0_set_shader_images(struct pipe_context *pipe, unsigned shader,
- unsigned start_slot, unsigned count,
- struct pipe_image_view *views)
+ unsigned start, unsigned nr,
+ struct pipe_image_view *images)
{
+ const unsigned s = nvc0_shader_stage(shader);
+ nvc0_bind_images_range(nvc0_context(pipe), s, start, nr, images);
+
+ if (s == 5)
+ nvc0_context(pipe)->dirty_cp |= NVC0_NEW_CP_SURFACES;
+ else
+ nvc0_context(pipe)->dirty_3d |= NVC0_NEW_3D_SURFACES;
}
static void
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
index d0d9315dd2b..b57db469109 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
@@ -665,6 +665,7 @@ nvc0_switch_pipe_context(struct nvc0_context *ctx_to)
ctx_to->textures_dirty[s] = ~0;
ctx_to->constbuf_dirty[s] = (1 << NVC0_MAX_PIPE_CONSTBUFS) - 1;
ctx_to->buffers_dirty[s] = ~0;
+ ctx_to->images_dirty[s] = ~0;
}
/* Reset tfb as the shader that owns it may have been deleted. */