summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nvc0
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2012-05-16 20:52:41 +0200
committerChristoph Bumiller <[email protected]>2012-05-17 15:24:58 +0200
commitfcb28682101dfa127486373411043d5d97a0ff8f (patch)
tree178155b68e55c7d7278c70cff3569c985677d428 /src/gallium/drivers/nvc0
parent07323a80a258372875e61f73a4f745374bea6bda (diff)
nv50,nvc0: handle user constbufs without wrapping them in a resource
Diffstat (limited to 'src/gallium/drivers/nvc0')
-rw-r--r--src/gallium/drivers/nvc0/nvc0_context.c5
-rw-r--r--src/gallium/drivers/nvc0/nvc0_context.h19
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.c2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.h3
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state.c45
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state_validate.c89
-rw-r--r--src/gallium/drivers/nvc0/nvc0_stateobj.h10
7 files changed, 91 insertions, 82 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c
index b0ab5bdc504..f93081465bd 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nvc0/nvc0_context.c
@@ -72,8 +72,9 @@ nvc0_context_unreference_resources(struct nvc0_context *nvc0)
for (i = 0; i < nvc0->num_textures[s]; ++i)
pipe_sampler_view_reference(&nvc0->textures[s][i], NULL);
- for (i = 0; i < 16; ++i)
- pipe_resource_reference(&nvc0->constbuf[s][i], NULL);
+ for (i = 0; i < NVC0_MAX_PIPE_CONSTBUFS; ++i)
+ if (!nvc0->constbuf[s][i].user)
+ pipe_resource_reference(&nvc0->constbuf[s][i].u.buf, NULL);
}
for (i = 0; i < nvc0->num_tfbbufs; ++i)
diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h
index d2dee03a19e..261cfb11007 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nvc0/nvc0_context.h
@@ -121,7 +121,7 @@ struct nvc0_context {
struct nvc0_program *gmtyprog;
struct nvc0_program *fragprog;
- struct pipe_resource *constbuf[5][16];
+ struct nvc0_constbuf constbuf[5][NVC0_MAX_PIPE_CONSTBUFS];
uint16_t constbuf_dirty[5];
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
@@ -168,6 +168,23 @@ nvc0_context(struct pipe_context *pipe)
return (struct nvc0_context *)pipe;
}
+static INLINE unsigned
+nvc0_shader_stage(unsigned pipe)
+{
+ switch (pipe) {
+ case PIPE_SHADER_VERTEX: return 0;
+/* case PIPE_SHADER_TESSELLATION_CONTROL: return 1; */
+/* case PIPE_SHADER_TESSELLATION_EVALUATION: return 2; */
+ case PIPE_SHADER_GEOMETRY: return 3;
+ case PIPE_SHADER_FRAGMENT: return 4;
+ case PIPE_SHADER_COMPUTE: return 5;
+ default:
+ assert(!"invalid PIPE_SHADER type");
+ return 0;
+ }
+}
+
+
/* nvc0_context.c */
struct pipe_context *nvc0_create(struct pipe_screen *, void *);
void nvc0_bufctx_fence(struct nvc0_context *, struct nouveau_bufctx *,
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index 5d6befd45b7..498207f613d 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -190,7 +190,7 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
case PIPE_SHADER_CAP_MAX_CONSTS:
return 65536 / 16;
case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
- return 14;
+ return NVC0_MAX_PIPE_CONSTBUFS;
case PIPE_SHADER_CAP_MAX_ADDRS:
return 1;
case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h b/src/gallium/drivers/nvc0/nvc0_screen.h
index 8bcc1470593..69cddf2c9b0 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nvc0/nvc0_screen.h
@@ -14,6 +14,9 @@
#define NVC0_TIC_MAX_ENTRIES 2048
#define NVC0_TSC_MAX_ENTRIES 2048
+/* doesn't count reserved slots (for auxiliary constants, immediates, etc.) */
+#define NVC0_MAX_PIPE_CONSTBUFS 14
+
struct nvc0_context;
struct nvc0_blitctx;
diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c
index 40161252a3d..cab238e7e06 100644
--- a/src/gallium/drivers/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nvc0/nvc0_state.c
@@ -620,38 +620,33 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
struct pipe_resource *res = cb ? cb->buffer : NULL;
+ const unsigned s = nvc0_shader_stage(shader);
+ const unsigned i = index;
- if (cb && cb->user_buffer) {
- res = nouveau_user_buffer_create(pipe->screen, cb->user_buffer,
- cb->buffer_size,
- PIPE_BIND_CONSTANT_BUFFER);
- }
+ if (shader == PIPE_SHADER_COMPUTE)
+ return;
- switch (shader) {
- case PIPE_SHADER_VERTEX: shader = 0; break;
- /*
- case PIPE_SHADER_TESSELLATION_CONTROL: shader = 1; break;
- case PIPE_SHADER_TESSELLATION_EVALUATION: shader = 2; break;
- */
- case PIPE_SHADER_GEOMETRY: shader = 3; break;
- case PIPE_SHADER_FRAGMENT: shader = 4; break;
- default:
- assert(0);
- break;
- }
+ 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_3d, NVC0_BIND_CB(s, i));
- if (nvc0->constbuf[shader][index])
- nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_CB(shader, index));
+ pipe_resource_reference(&nvc0->constbuf[s][i].u.buf, res);
- pipe_resource_reference(&nvc0->constbuf[shader][index], res);
+ nvc0->constbuf[s][i].user = (cb && cb->user_buffer) ? TRUE : FALSE;
+ if (nvc0->constbuf[s][i].user) {
+ nvc0->constbuf[s][i].u.data = cb->user_buffer;
+ nvc0->constbuf[s][i].size = cb->buffer_size;
+ } else
+ if (cb) {
+ nvc0->constbuf[s][i].offset = cb->buffer_offset;
+ nvc0->constbuf[s][i].size = align(cb->buffer_size, 0x100);
+ }
- nvc0->constbuf_dirty[shader] |= 1 << index;
+ nvc0->constbuf_dirty[s] |= 1 << i;
nvc0->dirty |= NVC0_NEW_CONSTBUF;
-
- if (cb->user_buffer) {
- pipe_resource_reference(&res, NULL);
- }
}
/* =============================================================================
diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c
index 5d34f2b0bcc..c2d115e715f 100644
--- a/src/gallium/drivers/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c
@@ -355,70 +355,53 @@ static void
nvc0_constbufs_validate(struct nvc0_context *nvc0)
{
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
- struct nouveau_bo *bo;
unsigned s;
for (s = 0; s < 5; ++s) {
- struct nv04_resource *res;
- int i;
-
while (nvc0->constbuf_dirty[s]) {
- unsigned base = 0;
- unsigned words = 0;
- boolean rebind = TRUE;
-
- i = ffs(nvc0->constbuf_dirty[s]) - 1;
+ int i = ffs(nvc0->constbuf_dirty[s]) - 1;
nvc0->constbuf_dirty[s] &= ~(1 << i);
- res = nv04_resource(nvc0->constbuf[s][i]);
- if (!res) {
- BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
- PUSH_DATA (push, (i << 4) | 0);
- if (i == 0)
- nvc0->state.uniform_buffer_bound[s] = 0;
- continue;
- }
-
- if (!nouveau_resource_mapped_by_gpu(&res->base)) {
- if (i == 0 && (res->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY)) {
- base = s << 16;
- bo = nvc0->screen->uniform_bo;
-
- if (nvc0->state.uniform_buffer_bound[s] >= res->base.width0)
- rebind = FALSE;
- else
- nvc0->state.uniform_buffer_bound[s] =
- align(res->base.width0, 0x100);
-
- words = res->base.width0 / 4;
- } else {
- nouveau_buffer_migrate(&nvc0->base, res, NOUVEAU_BO_VRAM);
- bo = res->bo;
- base = res->offset;
+ 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_3D(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_3D(CB_BIND(s)), 1);
+ PUSH_DATA (push, (0 << 4) | 1);
}
+ nvc0_cb_push(&nvc0->base, bo, NOUVEAU_BO_VRAM,
+ base, nvc0->state.uniform_buffer_bound[s],
+ 0, (size + 3) / 4,
+ nvc0->constbuf[s][0].u.data);
} else {
- bo = res->bo;
- base = res->offset;
+ struct nv04_resource *res =
+ nv04_resource(nvc0->constbuf[s][i].u.buf);
+ if (res) {
+ BEGIN_NVC0(push, NVC0_3D(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_3D(CB_BIND(s)), 1);
+ PUSH_DATA (push, (i << 4) | 1);
+
+ BCTX_REFN(nvc0->bufctx_3d, CB(s, i), res, RD);
+ } else {
+ BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
+ PUSH_DATA (push, (i << 4) | 0);
+ }
if (i == 0)
nvc0->state.uniform_buffer_bound[s] = 0;
}
-
- if (bo != nvc0->screen->uniform_bo)
- BCTX_REFN(nvc0->bufctx_3d, CB(s, i), res, RD);
-
- if (rebind) {
- BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
- PUSH_DATA (push, align(res->base.width0, 0x100));
- PUSH_DATAh(push, bo->offset + base);
- PUSH_DATA (push, bo->offset + base);
- BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
- PUSH_DATA (push, (i << 4) | 1);
- }
-
- if (words)
- nvc0_cb_push(&nvc0->base,
- bo, NOUVEAU_BO_VRAM, base, res->base.width0,
- 0, words, (const uint32_t *)res->data);
}
}
}
diff --git a/src/gallium/drivers/nvc0/nvc0_stateobj.h b/src/gallium/drivers/nvc0/nvc0_stateobj.h
index 16d336cfab2..5afbffb7d22 100644
--- a/src/gallium/drivers/nvc0/nvc0_stateobj.h
+++ b/src/gallium/drivers/nvc0/nvc0_stateobj.h
@@ -32,6 +32,16 @@ struct nvc0_zsa_stateobj {
uint32_t state[26];
};
+struct nvc0_constbuf {
+ union {
+ struct pipe_resource *buf;
+ const void *data;
+ } u;
+ uint32_t size;
+ uint16_t offset;
+ boolean user; /* should only be TRUE if u.data is valid and non-NULL */
+};
+
struct nvc0_vertex_element {
struct pipe_vertex_element pipe;
uint32_t state;