nv40: and vertprog..
authorBen Skeggs <skeggsb@gmail.com>
Mon, 18 Feb 2008 06:36:24 +0000 (17:36 +1100)
committerBen Skeggs <skeggsb@gmail.com>
Mon, 18 Feb 2008 06:36:24 +0000 (17:36 +1100)
src/gallium/drivers/nv40/nv40_context.h
src/gallium/drivers/nv40/nv40_fragprog.c
src/gallium/drivers/nv40/nv40_state.c
src/gallium/drivers/nv40/nv40_state.h
src/gallium/drivers/nv40/nv40_state_emit.c
src/gallium/drivers/nv40/nv40_vbo.c
src/gallium/drivers/nv40/nv40_vertprog.c

index ce0933f..28a0274 100644 (file)
@@ -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,
index bfc75eb..77ac8ab 100644 (file)
@@ -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
index 2886c6b..8ffbb13 100644 (file)
@@ -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) {
index 2701294..e5217fe 100644 (file)
@@ -39,6 +39,7 @@ struct nv40_vertex_program {
 
        uint32_t ir;
        uint32_t or;
+       struct nouveau_stateobj *so;
 };
 
 struct nv40_fragment_program_data {
index e10e178..e702b10 100644 (file)
@@ -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;
        }
 
index fa827ef..3bfcb26 100644 (file)
@@ -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;
index 9f4738b..4a15e51 100644 (file)
@@ -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
+       }
+};
+