diff options
-rw-r--r-- | src/gallium/drivers/nv40/nv40_context.h | 14 | ||||
-rw-r--r-- | src/gallium/drivers/nv40/nv40_fragprog.c | 10 | ||||
-rw-r--r-- | src/gallium/drivers/nv40/nv40_state.c | 5 | ||||
-rw-r--r-- | src/gallium/drivers/nv40/nv40_state.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/nv40/nv40_state_emit.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nv40/nv40_vbo.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nv40/nv40_vertprog.c | 57 |
7 files changed, 55 insertions, 37 deletions
diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index ce0933fea4a..28a0274d771 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -75,6 +75,7 @@ struct nv40_state { } stipple; struct nouveau_stateobj *fragprog; + struct nouveau_stateobj *vertprog; }; struct nv40_context { @@ -99,6 +100,7 @@ struct nv40_context { struct pipe_scissor_state scissor; unsigned stipple[32]; struct pipe_clip_state clip; + struct nv40_vertex_program *vertprog; struct nv40_fragment_program *fragprog; struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; } pipe_state; @@ -117,13 +119,6 @@ struct nv40_context { struct nouveau_stateobj *so_viewport; struct nouveau_stateobj *so_stipple; - struct { - struct nv40_vertex_program *active; - - struct nv40_vertex_program *current; - struct pipe_buffer *constant_buf; - } vertprog; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; }; @@ -151,10 +146,6 @@ extern void nv40_init_query_functions(struct nv40_context *nv40); extern struct draw_stage *nv40_draw_render_stage(struct nv40_context *nv40); /* nv40_vertprog.c */ -extern void nv40_vertprog_translate(struct nv40_context *, - struct nv40_vertex_program *); -extern void nv40_vertprog_bind(struct nv40_context *, - struct nv40_vertex_program *); extern void nv40_vertprog_destroy(struct nv40_context *, struct nv40_vertex_program *); @@ -172,6 +163,7 @@ extern struct nv40_state_entry nv40_state_clip; extern struct nv40_state_entry nv40_state_scissor; extern struct nv40_state_entry nv40_state_stipple; extern struct nv40_state_entry nv40_state_fragprog; +extern struct nv40_state_entry nv40_state_vertprog; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index bfc75eb4620..77ac8ab2c61 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -795,7 +795,6 @@ nv40_fragprog_validate(struct nv40_context *nv40) nv40->pipe_state.constbuf[PIPE_SHADER_FRAGMENT]; struct pipe_winsys *ws = nv40->pipe.winsys; struct nouveau_stateobj *so; - unsigned new_program = FALSE; int i; if (fp->translated) @@ -806,7 +805,6 @@ nv40_fragprog_validate(struct nv40_context *nv40) nv40->fallback |= NV40_FALLBACK_RAST; return FALSE; } - new_program = TRUE; fp->buffer = ws->buffer_create(ws, 0x100, 0, fp->insn_len * 4); nv40_fragprog_upload(nv40, fp); @@ -843,8 +841,12 @@ update_constants: nv40_fragprog_upload(nv40, fp); } - so_ref(fp->so, &nv40->state.fragprog); - return new_program; + if (fp->so != nv40->state.fragprog) { + so_ref(fp->so, &nv40->state.fragprog); + return TRUE; + } + + return FALSE; } void diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 2886c6b0dc4..8ffbb131f73 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -491,9 +491,8 @@ static void nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_vertex_program *vp = hwcso; - nv40->vertprog.current = vp; + nv40->pipe_state.vertprog = hwcso; nv40->dirty |= NV40_NEW_VERTPROG; } @@ -573,7 +572,7 @@ nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct nv40_context *nv40 = nv40_context(pipe); if (shader == PIPE_SHADER_VERTEX) { - nv40->vertprog.constant_buf = buf->buffer; + nv40->pipe_state.constbuf[PIPE_SHADER_VERTEX] = buf->buffer; nv40->dirty |= NV40_NEW_VERTPROG; } else if (shader == PIPE_SHADER_FRAGMENT) { diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index 2701294a077..e5217fe91c4 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -39,6 +39,7 @@ struct nv40_vertex_program { uint32_t ir; uint32_t or; + struct nouveau_stateobj *so; }; struct nv40_fragment_program_data { diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index e10e178432e..e702b103236 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -27,6 +27,7 @@ static struct nv40_state_entry *render_states[] = { &nv40_state_scissor, &nv40_state_stipple, &nv40_state_fragprog, + &nv40_state_vertprog, NULL }; @@ -116,7 +117,7 @@ nv40_emit_hw_state(struct nv40_context *nv40) } if (nv40->dirty & NV40_NEW_VERTPROG) { - nv40_vertprog_bind(nv40, nv40->vertprog.current); + so_emit(nv40->nvws, nv40->state.vertprog); nv40->dirty &= ~NV40_NEW_VERTPROG; } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index fa827ef0c5d..3bfcb264db1 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -101,7 +101,7 @@ static void nv40_vbo_arrays_update(struct nv40_context *nv40, struct pipe_buffer *ib, unsigned ib_format) { - struct nv40_vertex_program *vp = nv40->vertprog.active; + struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; struct nouveau_stateobj *vtxbuf, *vtxfmt; unsigned inputs, hw, num_hw; unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 9f4738b8308..4a15e51eb33 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -558,7 +558,7 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc) return TRUE; } -void +static void nv40_vertprog_translate(struct nv40_context *nv40, struct nv40_vertex_program *vp) { @@ -631,24 +631,32 @@ out_err: free(vpc); } -void -nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) +static boolean +nv40_vertprog_validate(struct nv40_context *nv40) { + struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; + struct pipe_buffer *constbuf = + nv40->pipe_state.constbuf[PIPE_SHADER_VERTEX]; struct nouveau_winsys *nvws = nv40->nvws; struct pipe_winsys *ws = nv40->pipe.winsys; boolean upload_code = FALSE, upload_data = FALSE; int i; /* Translate TGSI shader into hw bytecode */ + if (vp->translated) + goto check_gpu_resources; + + nv40_vertprog_translate(nv40, vp); if (!vp->translated) { - nv40_vertprog_translate(nv40, vp); - if (!vp->translated) - assert(0); + nv40->fallback |= NV40_FALLBACK_TNL; + return FALSE; } +check_gpu_resources: /* Allocate hw vtxprog exec slots */ if (!vp->exec) { struct nouveau_resource *heap = nv40->hw->vp_exec_heap; + struct nouveau_stateobj *so; uint vplen = vp->nr_insns; if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) { @@ -663,6 +671,15 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) assert(0); } + so = so_new(5, 0); + so_method(so, nv40->hw->curie, NV40TCL_VP_START_FROM_ID, 1); + so_data (so, vp->exec->start); + so_method(so, nv40->hw->curie, NV40TCL_VP_ATTRIB_EN, 2); + so_data (so, vp->ir); + so_data (so, vp->or); + so_ref(so, &vp->so); + so_ref(NULL, &so); + upload_code = TRUE; } @@ -725,8 +742,8 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) if (vp->nr_consts) { float *map = NULL; - if (nv40->vertprog.constant_buf) { - map = ws->buffer_map(ws, nv40->vertprog.constant_buf, + if (constbuf) { + map = ws->buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ); } @@ -747,9 +764,8 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) OUT_RINGp ((uint32_t *)vpd->value, 4); } - if (map) { - ws->buffer_unmap(ws, nv40->vertprog.constant_buf); - } + if (constbuf) + ws->buffer_unmap(ws, constbuf); } /* Upload vtxprog */ @@ -770,13 +786,12 @@ nv40_vertprog_bind(struct nv40_context *nv40, struct nv40_vertex_program *vp) } } - BEGIN_RING(curie, NV40TCL_VP_START_FROM_ID, 1); - OUT_RING (vp->exec->start); - BEGIN_RING(curie, NV40TCL_VP_ATTRIB_EN, 2); - OUT_RING (vp->ir); - OUT_RING (vp->or); + if (vp->so != nv40->state.vertprog) { + so_ref(vp->so, &nv40->state.vertprog); + return TRUE; + } - nv40->vertprog.active = vp; + return FALSE; } void @@ -788,3 +803,11 @@ nv40_vertprog_destroy(struct nv40_context *nv40, struct nv40_vertex_program *vp) free(vp->insns); } +struct nv40_state_entry nv40_state_vertprog = { + .validate = nv40_vertprog_validate, + .dirty = { + .pipe = NV40_NEW_VERTPROG, + .hw = NV40_NEW_VERTPROG + } +}; + |