diff options
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_context.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_program.c | 50 |
2 files changed, 39 insertions, 12 deletions
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 5214ce1a69..cbb473410a 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -30,6 +30,7 @@ #define NV50_CB_PGP 3 #define NV50_CB_TIC 4 #define NV50_CB_TSC 5 +#define NV50_CB_PUPLOAD 6 #define NV50_NEW_BLEND (1 << 0) #define NV50_NEW_ZSA (1 << 1) diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 2fe60ad51f..2cf6275730 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -1494,8 +1494,10 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) { struct pipe_winsys *ws = nv50->pipe.winsys; struct nv50_program_exec *e; + struct nouveau_stateobj *so; + const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR; + unsigned start, count, *up, *ptr; boolean upload = FALSE; - unsigned *map; if (!p->buffer) { p->buffer = ws->buffer_create(ws, 0x100, 0, p->exec_size * 4); @@ -1522,20 +1524,44 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) if (!upload) return FALSE; - map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); + up = ptr = MALLOC(p->exec_size * 4); for (e = p->exec_head; e; e = e->next) { -#ifdef NV50_PROGRAM_DUMP - NOUVEAU_ERR("0x%08x\n", e->inst[0]); -#endif - *(map++) = e->inst[0]; - if (is_long(e)) { -#ifdef NV50_PROGRAM_DUMP - NOUVEAU_ERR("0x%08x\n", e->inst[1]); -#endif - *(map++) = e->inst[1]; + *(ptr++) = e->inst[0]; + if (is_long(e)) + *(ptr++) = e->inst[1]; + } + + so = so_new(3,2); + so_method(so, nv50->screen->tesla, 0x1280, 3); + so_reloc (so, p->buffer, 0, flags | NOUVEAU_BO_HIGH, 0, 0); + so_reloc (so, p->buffer, 0, flags | NOUVEAU_BO_LOW, 0, 0); + so_data (so, (NV50_CB_PUPLOAD << 16) | 0x0800); //(p->exec_size * 4)); + + start = 0; count = p->exec_size; + while (count) { + struct nouveau_winsys *nvws = nv50->screen->nvws; + unsigned nr; + + so_emit(nvws, so); + + nr = MIN2(count, 2047); + nr = MIN2(nvws->channel->pushbuf->remaining, nr); + if (nvws->channel->pushbuf->remaining < (nr + 3)) { + FIRE_RING(NULL); + continue; } + + BEGIN_RING(tesla, 0x0f00, 1); + OUT_RING ((start << 8) | NV50_CB_PUPLOAD); + BEGIN_RING(tesla, 0x40000f04, nr); + OUT_RINGp (up + start, nr); + + start += nr; + count -= nr; } - ws->buffer_unmap(ws, p->buffer); + + FREE(up); + so_ref(NULL, &so); } void |