summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv50
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/nv50
parent07323a80a258372875e61f73a4f745374bea6bda (diff)
nv50,nvc0: handle user constbufs without wrapping them in a resource
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c5
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h17
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c7
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.h3
-rw-r--r--src/gallium/drivers/nv50/nv50_shader_state.c109
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c42
-rw-r--r--src/gallium/drivers/nv50/nv50_stateobj.h10
7 files changed, 110 insertions, 83 deletions
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 558fe0b3684..1e6bbaf8eb8 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -86,8 +86,9 @@ nv50_context_unreference_resources(struct nv50_context *nv50)
for (i = 0; i < nv50->num_textures[s]; ++i)
pipe_sampler_view_reference(&nv50->textures[s][i], NULL);
- for (i = 0; i < 16; ++i)
- pipe_resource_reference(&nv50->constbuf[s][i], NULL);
+ for (i = 0; i < NV50_MAX_PIPE_CONSTBUFS; ++i)
+ if (!nv50->constbuf[s][i].user)
+ pipe_resource_reference(&nv50->constbuf[s][i].u.buf, NULL);
}
}
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 44a0ba0f561..8f5363b3684 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -90,6 +90,7 @@ struct nv50_context {
uint32_t semantic_color;
uint32_t semantic_psize;
int32_t index_bias;
+ boolean uniform_buffer_bound[3];
boolean prim_restart;
boolean point_sprite;
boolean rt_serialize;
@@ -113,7 +114,7 @@ struct nv50_context {
struct nv50_program *gmtyprog;
struct nv50_program *fragprog;
- struct pipe_resource *constbuf[3][16];
+ struct nv50_constbuf constbuf[3][NV50_MAX_PIPE_CONSTBUFS];
uint16_t constbuf_dirty[3];
uint16_t constbuf_valid[3];
@@ -163,6 +164,20 @@ nv50_context_screen(struct nv50_context *nv50)
return nv50_screen(&nv50->base.screen->base);
}
+/* return index used in nv50_context arrays for a specific shader type */
+static INLINE unsigned
+nv50_context_shader_stage(unsigned pipe)
+{
+ switch (pipe) {
+ case PIPE_SHADER_VERTEX: return 0;
+ case PIPE_SHADER_FRAGMENT: return 1;
+ case PIPE_SHADER_GEOMETRY: return 2;
+ case PIPE_SHADER_COMPUTE: return 3;
+ default:
+ assert(!"invalid/unhandled shader type");
+ return 0;
+ }
+}
/* nv50_context.c */
struct pipe_context *nv50_create(struct pipe_screen *, void *);
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index c96e028b2a2..9f356ff6556 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -196,7 +196,7 @@ nv50_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 NV50_MAX_PIPE_CONSTBUFS;
case PIPE_SHADER_CAP_MAX_ADDRS:
return 1;
case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
@@ -437,10 +437,7 @@ nv50_screen_init_hwctx(struct nv50_screen *screen, unsigned tls_space)
PUSH_DATA (push, screen->uniforms->offset + (3 << 16));
PUSH_DATA (push, (NV50_CB_AUX << 16) | 0x0200);
- BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 6);
- PUSH_DATA (push, (NV50_CB_PVP << 12) | 0x001);
- PUSH_DATA (push, (NV50_CB_PGP << 12) | 0x021);
- PUSH_DATA (push, (NV50_CB_PFP << 12) | 0x031);
+ BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 3);
PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf01);
PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21);
PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31);
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h
index 9eae08ea1d3..4292f7fc9a6 100644
--- a/src/gallium/drivers/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -12,6 +12,9 @@
#define NV50_TIC_MAX_ENTRIES 2048
#define NV50_TSC_MAX_ENTRIES 2048
+/* doesn't count reserved slots (for auxiliary constants, immediates, etc.) */
+#define NV50_MAX_PIPE_CONSTBUFS 14
+
struct nv50_context;
#define NV50_CODE_BO_SIZE_LOG2 19
diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c
index d070f07bbbc..df6764b216f 100644
--- a/src/gallium/drivers/nv50/nv50_shader_state.c
+++ b/src/gallium/drivers/nv50/nv50_shader_state.c
@@ -35,9 +35,7 @@ nv50_constbufs_validate(struct nv50_context *nv50)
unsigned s;
for (s = 0; s < 3; ++s) {
- struct nv04_resource *res;
- int i;
- unsigned p, b;
+ unsigned p;
if (s == PIPE_SHADER_FRAGMENT)
p = NV50_3D_SET_PROGRAM_CB_PROGRAM_FRAGMENT;
@@ -48,68 +46,63 @@ nv50_constbufs_validate(struct nv50_context *nv50)
p = NV50_3D_SET_PROGRAM_CB_PROGRAM_VERTEX;
while (nv50->constbuf_dirty[s]) {
- struct nouveau_bo *bo;
- unsigned start = 0;
- unsigned words = 0;
-
- i = ffs(nv50->constbuf_dirty[s]) - 1;
+ const int i = ffs(nv50->constbuf_dirty[s]) - 1;
nv50->constbuf_dirty[s] &= ~(1 << i);
- res = nv04_resource(nv50->constbuf[s][i]);
- if (!res) {
- if (i != 0) {
+ if (nv50->constbuf[s][i].user) {
+ const unsigned b = NV50_CB_PVP + s;
+ unsigned start = 0;
+ unsigned words = nv50->constbuf[s][0].size / 4;
+ if (i) {
+ NOUVEAU_ERR("user constbufs only supported in slot 0\n");
+ continue;
+ }
+ if (!nv50->state.uniform_buffer_bound[s]) {
+ nv50->state.uniform_buffer_bound[s] = TRUE;
BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
- PUSH_DATA (push, (i << 8) | p | 0);
+ PUSH_DATA (push, (b << 12) | (i << 8) | p | 1);
+ }
+ while (words) {
+ unsigned nr;
+
+ if (!PUSH_SPACE(push, 16))
+ break;
+ nr = PUSH_AVAIL(push);
+ assert(nr >= 16);
+ nr = MIN2(MIN2(nr - 3, words), NV04_PFIFO_MAX_PACKET_LEN);
+
+ BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
+ PUSH_DATA (push, (start << 8) | b);
+ BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr);
+ PUSH_DATAp(push, &nv50->constbuf[s][0].u.data[start * 4], nr);
+
+ start += nr;
+ words -= nr;
}
- continue;
- }
-
- if (i == 0) {
- b = NV50_CB_PVP + s;
-
- /* always upload GL uniforms through CB DATA */
- bo = nv50->screen->uniforms;
- words = res->base.width0 / 4;
} else {
- b = s * 16 + i;
-
- assert(0);
-
- if (!nouveau_resource_mapped_by_gpu(&res->base)) {
- nouveau_buffer_migrate(&nv50->base, res, NOUVEAU_BO_VRAM);
+ struct nv04_resource *res =
+ nv04_resource(nv50->constbuf[s][i].u.buf);
+ if (res) {
+ /* TODO: allocate persistent bindings */
+ const unsigned b = s * 16 + i;
+
+ assert(nouveau_resource_mapped_by_gpu(&res->base));
+
+ BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, res->address + nv50->constbuf[s][i].offset);
+ PUSH_DATA (push, res->address + nv50->constbuf[s][i].offset);
+ PUSH_DATA (push, (b << 16) |
+ (nv50->constbuf[s][i].size & 0xffff));
+ BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
+ PUSH_DATA (push, (b << 12) | (i << 8) | p | 1);
- BEGIN_NV04(push, NV50_3D(CODE_CB_FLUSH), 1);
- PUSH_DATA (push, 0);
+ BCTX_REFN(nv50->bufctx_3d, CB(s, i), res, RD);
+ } else {
+ BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
+ PUSH_DATA (push, (i << 8) | p | 0);
}
- BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
- PUSH_DATAh(push, res->address);
- PUSH_DATA (push, res->address);
- PUSH_DATA (push, (b << 16) | (res->base.width0 & 0xffff));
- BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
- PUSH_DATA (push, (b << 12) | (i << 8) | p | 1);
-
- bo = res->bo;
- }
-
- if (bo != nv50->screen->uniforms)
- BCTX_REFN(nv50->bufctx_3d, CB(s, i), res, RD);
-
- while (words) {
- unsigned nr;
-
- if (!PUSH_SPACE(push, 16))
- break;
- nr = PUSH_AVAIL(push);
- assert(nr >= 16);
- nr = MIN2(MIN2(nr - 3, words), NV04_PFIFO_MAX_PACKET_LEN);
-
- BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
- PUSH_DATA (push, (start << 8) | b);
- BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr);
- PUSH_DATAp(push, &res->data[start * 4], nr);
-
- start += nr;
- words -= nr;
+ if (i == 0)
+ nv50->state.uniform_buffer_bound[s] = FALSE;
}
}
}
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 7f840e2b42e..eea3ffd5270 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -751,28 +751,36 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
{
struct nv50_context *nv50 = nv50_context(pipe);
struct pipe_resource *res = cb ? cb->buffer : NULL;
+ const unsigned s = nv50_context_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);
- }
-
- pipe_resource_reference(&nv50->constbuf[shader][index], res);
+ if (shader == PIPE_SHADER_COMPUTE)
+ return;
- nv50->constbuf_dirty[shader] |= 1 << index;
- if (res)
- nv50->constbuf_valid[shader] |= 1 << index;
+ if (nv50->constbuf[s][i].user)
+ nv50->constbuf[s][i].u.buf = NULL;
else
- nv50->constbuf_valid[shader] &= ~(1 << index);
-
- nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(shader, index));
+ if (nv50->constbuf[s][i].u.buf)
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(s, i));
+
+ pipe_resource_reference(&nv50->constbuf[s][i].u.buf, res);
+
+ nv50->constbuf[s][i].user = (cb && cb->user_buffer) ? TRUE : FALSE;
+ if (nv50->constbuf[s][i].user) {
+ nv50->constbuf[s][i].u.data = cb->user_buffer;
+ nv50->constbuf[s][i].size = cb->buffer_size;
+ nv50->constbuf_valid[s] |= 1 << i;
+ } else
+ if (res) {
+ nv50->constbuf[s][i].offset = cb->buffer_offset;
+ nv50->constbuf[s][i].size = align(cb->buffer_size, 0x100);
+ nv50->constbuf_valid[s] |= 1 << i;
+ } else {
+ nv50->constbuf_valid[s] &= ~(1 << i);
+ }
+ nv50->constbuf_dirty[s] |= 1 << i;
nv50->dirty |= NV50_NEW_CONSTBUF;
-
- if (cb && cb->user_buffer) {
- pipe_resource_reference(&res, NULL);
- }
}
/* =============================================================================
diff --git a/src/gallium/drivers/nv50/nv50_stateobj.h b/src/gallium/drivers/nv50/nv50_stateobj.h
index 8a9260c937e..eec146552b4 100644
--- a/src/gallium/drivers/nv50/nv50_stateobj.h
+++ b/src/gallium/drivers/nv50/nv50_stateobj.h
@@ -34,6 +34,16 @@ struct nv50_zsa_stateobj {
uint32_t state[29];
};
+struct nv50_constbuf {
+ union {
+ struct pipe_resource *buf;
+ const uint8_t *data;
+ } u;
+ uint32_t size; /* max 65536 */
+ uint16_t offset;
+ boolean user; /* should only be TRUE if u.data is valid and non-NULL */
+};
+
struct nv50_vertex_element {
struct pipe_vertex_element pipe;
uint32_t state;