nv50: hook up geometry programs
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sat, 16 Jan 2010 12:25:55 +0000 (13:25 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sat, 16 Jan 2010 17:07:31 +0000 (18:07 +0100)
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_screen.h
src/gallium/drivers/nv50/nv50_state.c
src/gallium/drivers/nv50/nv50_state_validate.c
src/gallium/drivers/nv50/nv50_tex.c
src/gallium/drivers/nv50/nv50_vbo.c

index 34cdac5a823d3bbd6e06ab4ee7ea2f51b93c40be..d024be6ea956cff4fb312c2530b911b3c5fa2d70 100644 (file)
 #define NV50_NEW_VERTPROG_CB   (1 << 9)
 #define NV50_NEW_FRAGPROG      (1 << 10)
 #define NV50_NEW_FRAGPROG_CB   (1 << 11)
-#define NV50_NEW_ARRAYS                (1 << 12)
-#define NV50_NEW_SAMPLER       (1 << 13)
-#define NV50_NEW_TEXTURE       (1 << 14)
+#define NV50_NEW_GEOMPROG      (1 << 12)
+#define NV50_NEW_GEOMPROG_CB   (1 << 13)
+#define NV50_NEW_ARRAYS                (1 << 14)
+#define NV50_NEW_SAMPLER       (1 << 15)
+#define NV50_NEW_TEXTURE       (1 << 16)
 
 struct nv50_blend_stateobj {
        struct pipe_blend_state pipe;
index 28e2b35deaaa664cece88ce5b162974152c408de..73205652cc403f266d733b57b890be76cab9f750 100644 (file)
@@ -167,7 +167,7 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
        struct nv50_screen *screen = nv50_screen(pscreen);
        unsigned i;
 
-       for (i = 0; i < 2; i++) {
+       for (i = 0; i < 3; i++) {
                if (screen->constbuf_parm[i])
                        nouveau_bo_ref(NULL, &screen->constbuf_parm[i]);
        }
@@ -329,7 +329,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
        so_ref(NULL, &so);
 
        /* Static tesla init */
-       so = so_new(40, 84, 20);
+       so = so_new(44, 90, 22);
 
        so_method(so, screen->tesla, NV50TCL_COND_MODE, 1);
        so_data  (so, NV50TCL_COND_MODE_ALWAYS);
@@ -352,10 +352,11 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
        so_data  (so, 0xf);
 
        /* max TIC (bits 4:8) & TSC (ignored) bindings, per program type */
-       so_method(so, screen->tesla, NV50TCL_TEX_LIMITS(0), 1);
-       so_data  (so, 0x54);
-       so_method(so, screen->tesla, NV50TCL_TEX_LIMITS(2), 1);
-       so_data  (so, 0x54);
+       for (i = 0; i < 3; ++i) {
+               so_method(so, screen->tesla, NV50TCL_TEX_LIMITS(i), 1);
+               so_data  (so, 0x54);
+       }
+
        /* origin is top left (set to 1 for bottom left) */
        so_method(so, screen->tesla, NV50TCL_Y_ORIGIN_BOTTOM, 1);
        so_data  (so, 0);
@@ -370,7 +371,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
                return NULL;
        }
 
-       for (i = 0; i < 2; i++) {
+       for (i = 0; i < 3; i++) {
                ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (128 * 4) * 4,
                                     &screen->constbuf_parm[i]);
                if (ret) {
@@ -406,22 +407,33 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
        so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
        so_data  (so, 0x00000001 | (NV50_CB_PMISC << 12));
        so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
+       so_data  (so, 0x00000021 | (NV50_CB_PMISC << 12));
+       so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
        so_data  (so, 0x00000031 | (NV50_CB_PMISC << 12));
 
        so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
-       so_reloc (so, screen->constbuf_parm[0], 0, NOUVEAU_BO_VRAM |
-                 NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
-       so_reloc (so, screen->constbuf_parm[0], 0, NOUVEAU_BO_VRAM |
-                 NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
+       so_reloc (so, screen->constbuf_parm[PIPE_SHADER_VERTEX], 0,
+                 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
+       so_reloc (so, screen->constbuf_parm[PIPE_SHADER_VERTEX], 0,
+                 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
        so_data  (so, (NV50_CB_PVP << 16) | 0x00000800);
        so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
        so_data  (so, 0x00000101 | (NV50_CB_PVP << 12));
 
        so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
-       so_reloc (so, screen->constbuf_parm[1], 0, NOUVEAU_BO_VRAM |
-                 NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
-       so_reloc (so, screen->constbuf_parm[1], 0, NOUVEAU_BO_VRAM |
-                 NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
+       so_reloc (so, screen->constbuf_parm[PIPE_SHADER_GEOMETRY], 0,
+                 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
+       so_reloc (so, screen->constbuf_parm[PIPE_SHADER_GEOMETRY], 0,
+                 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
+       so_data  (so, (NV50_CB_PGP << 16) | 0x00000800);
+       so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
+       so_data  (so, 0x00000121 | (NV50_CB_PGP << 12));
+
+       so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
+       so_reloc (so, screen->constbuf_parm[PIPE_SHADER_FRAGMENT], 0,
+                 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
+       so_reloc (so, screen->constbuf_parm[PIPE_SHADER_FRAGMENT], 0,
+                 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
        so_data  (so, (NV50_CB_PFP << 16) | 0x00000800);
        so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
        so_data  (so, 0x00000131 | (NV50_CB_PFP << 12));
index a038a4e3c2adee79addfa0a57229c6022699ab23..7a155ca9c45119729a85734ede22bc486d46177a 100644 (file)
@@ -18,10 +18,10 @@ struct nv50_screen {
        struct nouveau_notifier *sync;
 
        struct nouveau_bo *constbuf_misc[1];
-       struct nouveau_bo *constbuf_parm[2];
+       struct nouveau_bo *constbuf_parm[PIPE_SHADER_TYPES];
 
        struct nouveau_resource *immd_heap[1];
-       struct nouveau_resource *parm_heap[2];
+       struct nouveau_resource *parm_heap[PIPE_SHADER_TYPES];
 
        struct nouveau_bo *tic;
        struct nouveau_bo *tsc;
index 1bbbbdd5f08d279f7371b8ba42987363cfe31c32..6ab33be663dc47b3a3717f4796619bbc1dedb5c4 100644 (file)
@@ -531,7 +531,7 @@ nv50_vp_state_delete(struct pipe_context *pipe, void *hwcso)
        struct nv50_program *p = hwcso;
 
        nv50_program_destroy(nv50, p);
-       FREE((void*)p->pipe.tokens);
+       FREE((void *)p->pipe.tokens);
        FREE(p);
 }
 
@@ -563,7 +563,39 @@ nv50_fp_state_delete(struct pipe_context *pipe, void *hwcso)
        struct nv50_program *p = hwcso;
 
        nv50_program_destroy(nv50, p);
-       FREE((void*)p->pipe.tokens);
+       FREE((void *)p->pipe.tokens);
+       FREE(p);
+}
+
+static void *
+nv50_gp_state_create(struct pipe_context *pipe,
+                    const struct pipe_shader_state *cso)
+{
+       struct nv50_program *p = CALLOC_STRUCT(nv50_program);
+
+       p->pipe.tokens = tgsi_dup_tokens(cso->tokens);
+       p->type = PIPE_SHADER_GEOMETRY;
+       tgsi_scan_shader(p->pipe.tokens, &p->info);
+       return (void *)p;
+}
+
+static void
+nv50_gp_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+       struct nv50_context *nv50 = nv50_context(pipe);
+
+       nv50->fragprog = hwcso;
+       nv50->dirty |= NV50_NEW_GEOMPROG;
+}
+
+static void
+nv50_gp_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+       struct nv50_context *nv50 = nv50_context(pipe);
+       struct nv50_program *p = hwcso;
+
+       nv50_program_destroy(nv50, p);
+       FREE((void *)p->pipe.tokens);
        FREE(p);
 }
 
@@ -596,6 +628,10 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
        if (shader == PIPE_SHADER_FRAGMENT) {
                nv50->constbuf[PIPE_SHADER_FRAGMENT] = buf;
                nv50->dirty |= NV50_NEW_FRAGPROG_CB;
+       } else
+       if (shader == PIPE_SHADER_GEOMETRY) {
+               nv50->constbuf[PIPE_SHADER_GEOMETRY] = buf;
+               nv50->dirty |= NV50_NEW_GEOMPROG_CB;
        }
 }
 
@@ -696,6 +732,10 @@ nv50_init_state_functions(struct nv50_context *nv50)
        nv50->pipe.bind_fs_state = nv50_fp_state_bind;
        nv50->pipe.delete_fs_state = nv50_fp_state_delete;
 
+       nv50->pipe.create_gs_state = nv50_gp_state_create;
+       nv50->pipe.bind_gs_state = nv50_gp_state_bind;
+       nv50->pipe.delete_gs_state = nv50_gp_state_delete;
+
        nv50->pipe.set_blend_color = nv50_set_blend_color;
        nv50->pipe.set_clip_state = nv50_set_clip_state;
        nv50->pipe.set_constant_buffer = nv50_set_constant_buffer;
index 7d4e9a9dc8de9266e2041b20c71a529bc68b31a3..fcd07b59cd61fb5eb3234a2244503a7e71101175 100644 (file)
@@ -199,6 +199,8 @@ nv50_state_emit(struct nv50_context *nv50)
                        nv50->state.dirty |= NV50_NEW_VERTPROG;
                if (nv50->state.fragprog)
                        nv50->state.dirty |= NV50_NEW_FRAGPROG;
+               if (nv50->state.geomprog)
+                       nv50->state.dirty |= NV50_NEW_GEOMPROG;
                if (nv50->state.rast)
                        nv50->state.dirty |= NV50_NEW_RASTERIZER;
                if (nv50->state.blend_colour)
@@ -228,9 +230,14 @@ nv50_state_emit(struct nv50_context *nv50)
                so_emit(chan, nv50->state.vertprog);
        if (nv50->state.dirty & NV50_NEW_FRAGPROG)
                so_emit(chan, nv50->state.fragprog);
+       if (nv50->state.dirty & NV50_NEW_GEOMPROG && nv50->state.geomprog)
+               so_emit(chan, nv50->state.geomprog);
        if (nv50->state.dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
-                                NV50_NEW_RASTERIZER))
+                                NV50_NEW_GEOMPROG | NV50_NEW_RASTERIZER))
                so_emit(chan, nv50->state.fp_linkage);
+       if ((nv50->state.dirty & (NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG))
+           && nv50->state.gp_linkage)
+               so_emit(chan, nv50->state.gp_linkage);
        if (nv50->state.dirty & NV50_NEW_RASTERIZER)
                so_emit(chan, nv50->state.rast);
        if (nv50->state.dirty & NV50_NEW_BLEND_COLOUR)
@@ -291,10 +298,16 @@ nv50_state_validate(struct nv50_context *nv50)
        if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB))
                nv50_fragprog_validate(nv50);
 
+       if (nv50->dirty & (NV50_NEW_GEOMPROG | NV50_NEW_GEOMPROG_CB))
+               nv50_geomprog_validate(nv50);
+
        if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
-                          NV50_NEW_RASTERIZER))
+                          NV50_NEW_GEOMPROG | NV50_NEW_RASTERIZER))
                nv50_fp_linkage_validate(nv50);
 
+       if (nv50->dirty & (NV50_NEW_GEOMPROG | NV50_NEW_VERTPROG))
+               nv50_gp_linkage_validate(nv50);
+
        if (nv50->dirty & NV50_NEW_RASTERIZER)
                so_ref(nv50->rasterizer->so, &nv50->state.rast);
 
@@ -400,8 +413,9 @@ viewport_uptodate:
                for (i = 0; i < PIPE_SHADER_TYPES; ++i)
                        nr += nv50->sampler_nr[i];
 
-               so = so_new(1+ 5 * PIPE_SHADER_TYPES, 1+ 19 * PIPE_SHADER_TYPES
-                                       + nr * 8, PIPE_SHADER_TYPES * 2);
+               so = so_new(1 + 5 * PIPE_SHADER_TYPES,
+                           1 + 19 * PIPE_SHADER_TYPES + nr * 8,
+                           PIPE_SHADER_TYPES * 2);
 
                nv50_validate_samplers(nv50, so, PIPE_SHADER_VERTEX);
                nv50_validate_samplers(nv50, so, PIPE_SHADER_FRAGMENT);
index bef548b728673684caca98afe605bbd9b60763ed..871536dca9b7a82905997682e7aadd0f8d942a36 100644 (file)
@@ -155,7 +155,7 @@ static boolean
 nv50_validate_textures(struct nv50_context *nv50, struct nouveau_stateobj *so,
                       unsigned p)
 {
-       static const unsigned p_remap[PIPE_SHADER_TYPES] = { 0, 2 };
+       static const unsigned p_remap[PIPE_SHADER_TYPES] = { 0, 2, 1 };
 
        struct nouveau_grobj *eng2d = nv50->screen->eng2d;
        struct nouveau_grobj *tesla = nv50->screen->tesla;
index f2e510fba6181df3cb646866b64f3e275cbc060e..89a94d2fe81a9b977c5b9bcd82341e4780f4c989 100644 (file)
@@ -55,6 +55,14 @@ nv50_prim(unsigned mode)
        case PIPE_PRIM_QUADS: return NV50TCL_VERTEX_BEGIN_QUADS;
        case PIPE_PRIM_QUAD_STRIP: return NV50TCL_VERTEX_BEGIN_QUAD_STRIP;
        case PIPE_PRIM_POLYGON: return NV50TCL_VERTEX_BEGIN_POLYGON;
+       case PIPE_PRIM_LINES_ADJACENCY:
+               return NV50TCL_VERTEX_BEGIN_LINES_ADJACENCY;
+       case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+               return NV50TCL_VERTEX_BEGIN_LINE_STRIP_ADJACENCY;
+       case PIPE_PRIM_TRIANGLES_ADJACENCY:
+               return NV50TCL_VERTEX_BEGIN_TRIANGLES_ADJACENCY;
+       case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
+               return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP_ADJACENCY;
        default:
                break;
        }