summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv50/nv50_program.c
diff options
context:
space:
mode:
authorBen Skeggs <[email protected]>2008-06-12 13:11:41 +1000
committerBen Skeggs <[email protected]>2008-06-29 15:46:17 +1000
commitab3d55e2e3578db8deba84dcf47a024071486bd8 (patch)
tree4e29acb9d699c80b35f75f082334b084e941e780 /src/gallium/drivers/nv50/nv50_program.c
parentaea1669ff221f97682f0be6a60632e40c2739d09 (diff)
nv50: more efficient const upload + fixes (fp/* works now!)
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_program.c')
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c48
1 files changed, 31 insertions, 17 deletions
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index cbbecafb028..4c41e5a7c24 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -1420,20 +1420,35 @@ out_cleanup:
static void
nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p)
{
- struct nv50_program_exec *e;
-
if (nv50_program_tx(p) == FALSE)
assert(0);
p->translated = TRUE;
}
static void
+nv50_program_upload_data(struct nv50_context *nv50, float *map,
+ unsigned start, unsigned count)
+{
+ while (count) {
+ unsigned nr = count > 2047 ? 2047 : count;
+
+ BEGIN_RING(tesla, 0x00000f00, 1);
+ OUT_RING ((NV50_CB_PMISC << 0) | (start << 8));
+ BEGIN_RING(tesla, 0x40000f04, nr);
+ OUT_RINGp (map, nr);
+
+ map += nr;
+ start += nr;
+ count -= nr;
+ }
+}
+
+static void
nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)
{
struct nouveau_winsys *nvws = nv50->screen->nvws;
struct pipe_winsys *ws = nv50->pipe.winsys;
unsigned nr = p->param_nr + p->immd_nr;
- int i;
if (!p->data && nr) {
struct nouveau_resource *heap = nv50->screen->vp_data_heap;
@@ -1452,20 +1467,15 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)
if (p->param_nr) {
float *map = ws->buffer_map(ws, nv50->constbuf[p->type],
PIPE_BUFFER_USAGE_CPU_READ);
- for (i = 0; i < p->param_nr; i++) {
- BEGIN_RING(tesla, 0x0f00, 2);
- OUT_RING ((NV50_CB_PMISC << 0) |
- ((p->data->start + i) << 8));
- OUT_RING (fui(map[i]));
- }
+ nv50_program_upload_data(nv50, map, p->data->start,
+ p->param_nr);
ws->buffer_unmap(ws, nv50->constbuf[p->type]);
}
- for (i = 0; i < p->immd_nr; i++) {
- BEGIN_RING(tesla, 0x0f00, 2);
- OUT_RING ((NV50_CB_PMISC << 0) |
- ((p->data_start + p->param_nr + i) << 8));
- OUT_RING (fui(p->immd[i]));
+ if (p->immd_nr) {
+ nv50_program_upload_data(nv50, p->immd,
+ p->data->start + p->param_nr,
+ p->immd_nr);
}
}
@@ -1481,11 +1491,15 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
if (p->data && p->data->start != p->data_start) {
for (e = p->exec_head; e; e = e->next) {
+ unsigned ei, ci;
+
if (e->param.index < 0)
continue;
- e->inst[e->param.shift / 32] &= ~e->param.mask;
- e->inst[e->param.shift / 32] |= (e->param.index <<
- e->param.shift);
+ ei = e->param.shift >> 5;
+ ci = e->param.index + p->data->start;
+
+ e->inst[ei] &= ~e->param.mask;
+ e->inst[ei] |= (ci << e->param.shift);
}
p->data_start = p->data->start;