nv30: Emit vertex program using state objects
authorPatrice Mandin <pmandin@caramail.com>
Fri, 11 Jul 2008 22:19:15 +0000 (00:19 +0200)
committerPatrice Mandin <pmandin@caramail.com>
Fri, 11 Jul 2008 22:19:15 +0000 (00:19 +0200)
src/gallium/drivers/nv30/nv30_context.h
src/gallium/drivers/nv30/nv30_state.c
src/gallium/drivers/nv30/nv30_state.h
src/gallium/drivers/nv30/nv30_state_emit.c
src/gallium/drivers/nv30/nv30_vbo.c
src/gallium/drivers/nv30/nv30_vertprog.c

index c3c8b733090c62324ca8055e5152ca5b7a943e75..5d7080a555dd5856df94ebb1a9c61b4cf246e2da 100644 (file)
@@ -124,6 +124,7 @@ struct nv30_context {
        unsigned dirty;
        struct pipe_scissor_state scissor;
        unsigned stipple[32];
+       struct nv30_vertex_program *vertprog;
        struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
        unsigned constbuf_nr[PIPE_SHADER_TYPES];
        struct nv30_rasterizer_state *rasterizer;
@@ -150,11 +151,6 @@ struct nv30_context {
                unsigned delta;
        } vb[16];
 
-       struct {
-               struct nv30_vertex_program *active;
-               struct nv30_vertex_program *current;
-       } vertprog;
-
        struct {
                struct nv30_fragment_program *active;
                struct nv30_fragment_program *current;
@@ -188,10 +184,6 @@ extern void nv30_screen_init_miptree_functions(struct pipe_screen *pscreen);
 extern struct draw_stage *nv30_draw_render_stage(struct nv30_context *nv30);
 
 /* nv30_vertprog.c */
-extern void nv30_vertprog_translate(struct nv30_context *,
-                                   struct nv30_vertex_program *);
-extern void nv30_vertprog_bind(struct nv30_context *,
-                              struct nv30_vertex_program *);
 extern void nv30_vertprog_destroy(struct nv30_context *,
                                  struct nv30_vertex_program *);
 
@@ -213,6 +205,7 @@ extern void nv30_state_tex_update(struct nv30_context *nv30);
 extern struct nv30_state_entry nv30_state_rasterizer;
 extern struct nv30_state_entry nv30_state_scissor;
 extern struct nv30_state_entry nv30_state_stipple;
+extern struct nv30_state_entry nv30_state_vertprog;
 extern struct nv30_state_entry nv30_state_blend;
 extern struct nv30_state_entry nv30_state_blend_colour;
 extern struct nv30_state_entry nv30_state_zsa;
index aec6fa2b1556532f3960f7213aaf3956592bec5f..92695ce23c02277fcf3a57453246c06b2156d826 100644 (file)
@@ -499,10 +499,12 @@ static void *
 nv30_vp_state_create(struct pipe_context *pipe,
                     const struct pipe_shader_state *cso)
 {
+       /*struct nv30_context *nv30 = nv30_context(pipe);*/
        struct nv30_vertex_program *vp;
 
        vp = CALLOC(1, sizeof(struct nv30_vertex_program));
        vp->pipe = *cso;
+       /*vp->draw = draw_create_vertex_shader(nv30->draw, &vp->pipe);*/
 
        return (void *)vp;
 }
@@ -511,14 +513,10 @@ static void
 nv30_vp_state_bind(struct pipe_context *pipe, void *hwcso)
 {
        struct nv30_context *nv30 = nv30_context(pipe);
-       struct nv30_vertex_program *vp = hwcso;
-
-       if (!hwcso) {
-               return;
-       }
 
-       nv30->vertprog.current = vp;
+       nv30->vertprog = hwcso;
        nv30->dirty |= NV30_NEW_VERTPROG;
+       /*nv30->draw_dirty |= NV30_NEW_VERTPROG;*/
 }
 
 static void
@@ -527,6 +525,7 @@ nv30_vp_state_delete(struct pipe_context *pipe, void *hwcso)
        struct nv30_context *nv30 = nv30_context(pipe);
        struct nv30_vertex_program *vp = hwcso;
 
+       /*draw_delete_vertex_shader(nv30->draw, vp->draw);*/
        nv30_vertprog_destroy(nv30, vp);
        FREE(vp);
 }
index c65a937467ed2f50dad9c6e8a5436ae9184fb01a..a897bc50687534bfbac26150293fc8727b084580 100644 (file)
@@ -26,6 +26,7 @@ struct nv30_vertex_program {
        struct pipe_shader_state pipe;
 
        boolean translated;
+
        struct nv30_vertex_program_exec *insns;
        unsigned nr_insns;
        struct nv30_vertex_program_data *consts;
@@ -39,6 +40,7 @@ struct nv30_vertex_program {
 
        uint32_t ir;
        uint32_t or;
+       struct nouveau_stateobj *so;
 };
 
 struct nv30_fragment_program_data {
index cf10ddd4b637f876dcc3ce6f19da9d012aba87a4..4ab62ddc0162e26a1dec70bdbc61fff8776b63df 100644 (file)
@@ -7,6 +7,7 @@ static struct nv30_state_entry *render_states[] = {
        &nv30_state_scissor,
        &nv30_state_stipple,
        &nv30_state_fragtex,
+       &nv30_state_vertprog,
        &nv30_state_blend,
        &nv30_state_blend_colour,
        &nv30_state_zsa,
@@ -74,11 +75,6 @@ nv30_emit_hw_state(struct nv30_context *nv30)
                states &= ~(1ULL << i);
        }
 
-       if (nv30->dirty & NV30_NEW_VERTPROG) {
-               nv30_vertprog_bind(nv30, nv30->vertprog.current);
-               nv30->dirty &= ~NV30_NEW_VERTPROG;
-       }
-
        so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FB]);
        for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
                if (!(samplers & (1 << i)))
index d23164eb485eab3adac4c0b788172ba2c0692f02..8e4ee7a8742bf9f63c299e97078179c510fa9d51 100644 (file)
@@ -100,7 +100,7 @@ nv30_vbo_static_attrib(struct nv30_context *nv30, int attrib,
 static void
 nv30_vbo_arrays_update(struct nv30_context *nv30)
 {
-       struct nv30_vertex_program *vp = nv30->vertprog.active;
+       struct nv30_vertex_program *vp = nv30->vertprog;
        uint32_t inputs, vtxfmt[16];
        int hw, num_hw = 0;
 
index 90756febd28e0ddd484b0c8526a668ac33bd1e95..65e00132055d833db1d941d71393586d857138c2 100644 (file)
@@ -563,7 +563,7 @@ nv30_vertprog_prepare(struct nv30_vpc *vpc)
        return TRUE;
 }
 
-void
+static void
 nv30_vertprog_translate(struct nv30_context *nv30,
                        struct nv30_vertex_program *vp)
 {
@@ -636,27 +636,31 @@ out_err:
        FREE(vpc);
 }
 
-void
-nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp)
+static boolean
+nv30_vertprog_validate(struct nv30_context *nv30)
 { 
        struct nouveau_winsys *nvws = nv30->nvws;
        struct pipe_winsys *ws = nv30->pipe.winsys;
+       struct nouveau_grobj *rankine = nv30->screen->rankine;
+       struct nv30_vertex_program *vp;
        struct pipe_buffer *constbuf;
        boolean upload_code = FALSE, upload_data = FALSE;
        int i;
 
+       vp = nv30->vertprog;
        constbuf = nv30->constbuf[PIPE_SHADER_VERTEX];
 
        /* Translate TGSI shader into hw bytecode */
        if (!vp->translated) {
                nv30_vertprog_translate(nv30, vp);
                if (!vp->translated)
-                       assert(0);
+                       return FALSE;
        }
 
        /* Allocate hw vtxprog exec slots */
        if (!vp->exec) {
                struct nouveau_resource *heap = nv30->screen->vp_exec_heap;
+               struct nouveau_stateobj *so;
                uint vplen = vp->nr_insns;
 
                if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) {
@@ -671,6 +675,15 @@ nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp)
                                assert(0);
                }
 
+               so = so_new(2, 0);
+               so_method(so, rankine, NV34TCL_VP_START_FROM_ID, 1);
+               so_data  (so, vp->exec->start);
+               /* Add these, and you'll go 1/3 speed */
+               /*so_method(so, rankine, NV34TCL_VP_ATTRIB_EN, 2);
+               so_data  (so, vp->ir);
+               so_data  (so, vp->or);*/
+               so_ref(so, &vp->so);
+
                upload_code = TRUE;
        }
 
@@ -777,10 +790,12 @@ nv30_vertprog_bind(struct nv30_context *nv30, struct nv30_vertex_program *vp)
                }
        }
 
-       BEGIN_RING(rankine, NV34TCL_VP_START_FROM_ID, 1);
-       OUT_RING  (vp->exec->start);
+       if (vp->so != nv30->state.hw[NV30_STATE_VERTPROG]) {
+               so_ref(vp->so, &nv30->state.hw[NV30_STATE_VERTPROG]);
+               return TRUE;
+       }
 
-       nv30->vertprog.active = vp;
+       return FALSE;
 }
 
 void
@@ -808,7 +823,14 @@ nv30_vertprog_destroy(struct nv30_context *nv30, struct nv30_vertex_program *vp)
        vp->data_start = 0;
        vp->data_start_min = 0;
 
-       /* vp->ir = vp->or = vp->clip_ctrl = 0;
-       so_ref(NULL, &vp->so); */
+       vp->ir = vp->or = 0;
+       so_ref(NULL, &vp->so);
 }
 
+struct nv30_state_entry nv30_state_vertprog = {
+       .validate = nv30_vertprog_validate,
+       .dirty = {
+               .pipe = NV30_NEW_VERTPROG /*| NV30_NEW_UCP*/,
+               .hw = NV30_STATE_VERTPROG,
+       }
+};