summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2016-01-11 15:35:21 +0100
committerSamuel Pitoiset <[email protected]>2016-02-21 10:41:25 +0100
commit57d4251003f4ed284179171bebaa2463675440d6 (patch)
treedf94d3601eb519ce0ef188abcfc97edb25ecc0a5
parent53f92bb7f903cc82dc1b1851bb7da3ee8469ab4a (diff)
nvc0: bind constant buffers for compute on Fermi
Loosely based on 3D. Changs from v3: - invalidate COMPUTE CBs after validating 3D CBs because they are aliased Changes from v2: - get rid of the 's' param to nvc0_cb_bo_push() because it doesn't matter to upload constbufs for compute using the 3d chan Signed-off-by: Samuel Pitoiset <[email protected]> Reviewed-by: Ilia Mirkin <[email protected]>
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_compute.c72
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_context.c11
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_screen.h2
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_state.c4
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c5
5 files changed, 81 insertions, 13 deletions
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
index 5c7dc0e1cf8..0fe6353b2ab 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
@@ -138,11 +138,71 @@ nvc0_compute_validate_program(struct nvc0_context *nvc0)
return false;
}
+static void
+nvc0_compute_validate_constbufs(struct nvc0_context *nvc0)
+{
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+ const int s = 5;
+
+ while (nvc0->constbuf_dirty[s]) {
+ int i = ffs(nvc0->constbuf_dirty[s]) - 1;
+ nvc0->constbuf_dirty[s] &= ~(1 << i);
+
+ if (nvc0->constbuf[s][i].user) {
+ struct nouveau_bo *bo = nvc0->screen->uniform_bo;
+ const unsigned base = s << 16;
+ const unsigned size = nvc0->constbuf[s][0].size;
+ assert(i == 0); /* we really only want OpenGL uniforms here */
+ assert(nvc0->constbuf[s][0].u.data);
+
+ if (nvc0->state.uniform_buffer_bound[s] < size) {
+ nvc0->state.uniform_buffer_bound[s] = align(size, 0x100);
+
+ BEGIN_NVC0(push, NVC0_COMPUTE(CB_SIZE), 3);
+ PUSH_DATA (push, nvc0->state.uniform_buffer_bound[s]);
+ PUSH_DATAh(push, bo->offset + base);
+ PUSH_DATA (push, bo->offset + base);
+ BEGIN_NVC0(push, NVC0_COMPUTE(CB_BIND), 1);
+ PUSH_DATA (push, (0 << 8) | 1);
+ }
+ nvc0_cb_bo_push(&nvc0->base, bo, NV_VRAM_DOMAIN(&nvc0->screen->base),
+ base, nvc0->state.uniform_buffer_bound[s],
+ 0, (size + 3) / 4,
+ nvc0->constbuf[s][0].u.data);
+ } else {
+ struct nv04_resource *res =
+ nv04_resource(nvc0->constbuf[s][i].u.buf);
+ if (res) {
+ BEGIN_NVC0(push, NVC0_COMPUTE(CB_SIZE), 3);
+ PUSH_DATA (push, nvc0->constbuf[s][i].size);
+ PUSH_DATAh(push, res->address + nvc0->constbuf[s][i].offset);
+ PUSH_DATA (push, res->address + nvc0->constbuf[s][i].offset);
+ BEGIN_NVC0(push, NVC0_COMPUTE(CB_BIND), 1);
+ PUSH_DATA (push, (i << 8) | 1);
+
+ BCTX_REFN(nvc0->bufctx_cp, CP_CB(i), res, RD);
+
+ res->cb_bindings[s] |= 1 << i;
+ } else {
+ BEGIN_NVC0(push, NVC0_COMPUTE(CB_BIND), 1);
+ PUSH_DATA (push, (i << 8) | 0);
+ }
+ if (i == 0)
+ nvc0->state.uniform_buffer_bound[s] = 0;
+ }
+ }
+
+ BEGIN_NVC0(push, NVC0_COMPUTE(FLUSH), 1);
+ PUSH_DATA (push, NVC0_COMPUTE_FLUSH_CB);
+}
+
static bool
nvc0_compute_state_validate(struct nvc0_context *nvc0)
{
if (!nvc0_compute_validate_program(nvc0))
return false;
+ if (nvc0->dirty_cp & NVC0_NEW_CP_CONSTBUF)
+ nvc0_compute_validate_constbufs(nvc0);
/* TODO: textures, samplers, surfaces, global memory buffers */
@@ -188,7 +248,7 @@ nvc0_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
struct nvc0_context *nvc0 = nvc0_context(pipe);
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_program *cp = nvc0->compprog;
- unsigned s, i;
+ unsigned s;
int ret;
ret = !nvc0_compute_state_validate(nvc0);
@@ -242,14 +302,10 @@ nvc0_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
BEGIN_NVC0(push, SUBC_COMPUTE(0x0360), 1);
PUSH_DATA (push, 0x1);
- /* rebind all the 3D constant buffers
- * (looks like binding a CB on COMPUTE clobbers 3D state) */
+ /* Invalidate all 3D constbufs because they are aliased with COMPUTE. */
nvc0->dirty |= NVC0_NEW_CONSTBUF;
for (s = 0; s < 5; s++) {
- for (i = 0; i < NVC0_MAX_PIPE_CONSTBUFS; i++)
- if (nvc0->constbuf[s][i].u.buf)
- nvc0->constbuf_dirty[s] |= 1 << i;
+ nvc0->constbuf_dirty[s] |= nvc0->constbuf_valid[s];
+ nvc0->state.uniform_buffer_bound[s] = 0;
}
- memset(nvc0->state.uniform_buffer_bound, 0,
- sizeof(nvc0->state.uniform_buffer_bound));
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
index 547b8f5d309..4fed7b24a76 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
@@ -241,15 +241,20 @@ nvc0_invalidate_resource_storage(struct nouveau_context *ctx,
}
}
- for (s = 0; s < 5; ++s) {
+ for (s = 0; s < 6; ++s) {
for (i = 0; i < NVC0_MAX_PIPE_CONSTBUFS; ++i) {
if (!(nvc0->constbuf_valid[s] & (1 << i)))
continue;
if (!nvc0->constbuf[s][i].user &&
nvc0->constbuf[s][i].u.buf == res) {
- nvc0->dirty |= NVC0_NEW_CONSTBUF;
nvc0->constbuf_dirty[s] |= 1 << i;
- nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_CB(s, i));
+ if (unlikely(s == 5)) {
+ nvc0->dirty_cp |= NVC0_NEW_CP_CONSTBUF;
+ nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_CB(i));
+ } else {
+ nvc0->dirty |= NVC0_NEW_CONSTBUF;
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_CB(s, i));
+ }
if (!--ref)
return ref;
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
index e86fe432e36..8487abcf999 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
@@ -51,7 +51,7 @@ struct nvc0_graph_state {
uint8_t c14_bound; /* whether immediate array constbuf is bound */
uint8_t clip_enable;
uint32_t clip_mode;
- uint32_t uniform_buffer_bound[5];
+ uint32_t uniform_buffer_bound[6];
struct nvc0_transform_feedback_state *tfb;
bool seamless_cube_map;
};
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
index 448211fca14..157d628d849 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
@@ -839,7 +839,9 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
const unsigned i = index;
if (unlikely(shader == PIPE_SHADER_COMPUTE)) {
- assert(!cb || !cb->user_buffer);
+ if (nvc0->constbuf[s][i].user)
+ nvc0->constbuf[s][i].u.buf = NULL;
+ else
if (nvc0->constbuf[s][i].u.buf)
nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_CB(i));
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
index 5ac3676cb76..2a210e99022 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
@@ -467,6 +467,11 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
}
}
}
+
+ /* Invalidate all COMPUTE constbufs because they are aliased with 3D. */
+ nvc0->dirty_cp |= NVC0_NEW_CP_CONSTBUF;
+ nvc0->constbuf_dirty[5] |= nvc0->constbuf_valid[5];
+ nvc0->state.uniform_buffer_bound[5] = 0;
}
static void