Mesa (master): nv50: hook up geometry programs

Christoph Bumiller chrisbmr at kemper.freedesktop.org
Sat Jan 16 17:08:52 UTC 2010


Module: Mesa
Branch: master
Commit: 4c223aaa3b1209006454d600cabc7547fa259a13
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4c223aaa3b1209006454d600cabc7547fa259a13

Author: Christoph Bumiller <e0425955 at student.tuwien.ac.at>
Date:   Sat Jan 16 13:25:55 2010 +0100

nv50: hook up geometry programs

---

 src/gallium/drivers/nv50/nv50_context.h        |    8 +++--
 src/gallium/drivers/nv50/nv50_screen.c         |   42 ++++++++++++++--------
 src/gallium/drivers/nv50/nv50_screen.h         |    4 +-
 src/gallium/drivers/nv50/nv50_state.c          |   44 ++++++++++++++++++++++-
 src/gallium/drivers/nv50/nv50_state_validate.c |   22 ++++++++++--
 src/gallium/drivers/nv50/nv50_tex.c            |    2 +-
 src/gallium/drivers/nv50/nv50_vbo.c            |    8 ++++
 7 files changed, 103 insertions(+), 27 deletions(-)

diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 34cdac5..d024be6 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -45,9 +45,11 @@
 #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;
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index 28e2b35..7320565 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -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));
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h
index a038a4e..7a155ca 100644
--- a/src/gallium/drivers/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -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;
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 1bbbbdd..6ab33be 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -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;
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index 7d4e9a9..fcd07b5 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -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);
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index bef548b..871536d 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -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;
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index f2e510f..89a94d2 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -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;
 	}




More information about the mesa-commit mailing list