Mesa (gallium-vertexelementcso): nv50: adapt to vertex elements cso

Christoph Bumiller chrisbmr at kemper.freedesktop.org
Fri Feb 26 05:21:24 PST 2010


Module: Mesa
Branch: gallium-vertexelementcso
Commit: f2656c3e3cc91edcbf572d175efe9346a30b1da2
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f2656c3e3cc91edcbf572d175efe9346a30b1da2

Author: Christoph Bumiller <e0425955 at student.tuwien.ac.at>
Date:   Fri Feb 26 14:16:46 2010 +0100

nv50: adapt to vertex elements cso

---

 src/gallium/drivers/nv50/nv50_context.h |   10 +++-
 src/gallium/drivers/nv50/nv50_state.c   |   34 ++++++++++--
 src/gallium/drivers/nv50/nv50_vbo.c     |   84 ++++++++++++++++++-------------
 3 files changed, 85 insertions(+), 43 deletions(-)

diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index b4de3e2..811b3ef 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -72,6 +72,12 @@ struct nv50_sampler_stateobj {
 	unsigned tsc[8];
 };
 
+struct nv50_vtxelt_stateobj {
+	struct pipe_vertex_element pipe[16];
+	unsigned num_elements;
+	uint32_t hw[16];
+};
+
 static INLINE unsigned
 get_tile_height(uint32_t tile_mode)
 {
@@ -168,8 +174,7 @@ struct nv50_context {
 	struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
 	struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
 	unsigned vtxbuf_nr;
-	struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
-	unsigned vtxelt_nr;
+	struct nv50_vtxelt_stateobj *vtxelt;
 	struct nv50_sampler_stateobj *sampler[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
 	unsigned sampler_nr[PIPE_SHADER_TYPES];
 	struct nv50_miptree *miptree[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
@@ -217,6 +222,7 @@ extern void nv50_draw_elements_instanced(struct pipe_context *pipe,
 					 unsigned count,
 					 unsigned startInstance,
 					 unsigned instanceCount);
+extern void nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso);
 extern void nv50_vbo_validate(struct nv50_context *nv50);
 
 /* nv50_clear.c */
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 7d30490..ffbf347 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -720,15 +720,34 @@ nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
 	nv50->dirty |= NV50_NEW_ARRAYS;
 }
 
+static void *
+nv50_vtxelts_state_create(struct pipe_context *pipe,
+			  unsigned num_elements,
+			  const struct pipe_vertex_element *elements)
+{
+	struct nv50_vtxelt_stateobj *cso = CALLOC_STRUCT(nv50_vtxelt_stateobj);
+
+	assert(num_elements < 16); /* not doing fallbacks yet */
+	cso->num_elements = num_elements;
+	memcpy(cso->pipe, elements, num_elements * sizeof(*elements));
+
+	nv50_vtxelt_construct(cso);
+
+	return (void *)cso;
+}
+
 static void
-nv50_set_vertex_elements(struct pipe_context *pipe, unsigned count,
-			 const struct pipe_vertex_element *ve)
+nv50_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso)
 {
-	struct nv50_context *nv50 = nv50_context(pipe);
+	FREE(hwcso);
+}
 
-	memcpy(nv50->vtxelt, ve, sizeof(*ve) * count);
-	nv50->vtxelt_nr = count;
+static void
+nv50_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+	struct nv50_context *nv50 = nv50_context(pipe);
 
+	nv50->vtxelt = hwcso;
 	nv50->dirty |= NV50_NEW_ARRAYS;
 }
 
@@ -778,7 +797,10 @@ nv50_init_state_functions(struct nv50_context *nv50)
 	nv50->pipe.set_scissor_state = nv50_set_scissor_state;
 	nv50->pipe.set_viewport_state = nv50_set_viewport_state;
 
+	nv50->pipe.create_vertex_elements_state = nv50_vtxelts_state_create;
+	nv50->pipe.delete_vertex_elements_state = nv50_vtxelts_state_delete;
+	nv50->pipe.bind_vertex_elements_state = nv50_vtxelts_state_bind;
+
 	nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers;
-	nv50->pipe.set_vertex_elements = nv50_set_vertex_elements;
 }
 
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index 909d323..c1dcb93 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -223,11 +223,10 @@ nv50_set_static_vtxattr(struct nv50_context *nv50, unsigned i, void *data)
 	struct nouveau_grobj *tesla = nv50->screen->tesla;
 	struct nouveau_channel *chan = tesla->channel;
 	float v[4];
-	unsigned nr_components = util_format_get_nr_components(nv50->vtxelt[i].src_format);
-	
+	enum pipe_format pf = nv50->vtxelt->pipe[i].src_format;
+	unsigned nr_components = util_format_get_nr_components(pf);
 
-	util_format_read_4f(nv50->vtxelt[i].src_format,
-			    v, 0, data, 0, 0, 0, 1, 1);
+	util_format_read_4f(pf, v, 0, data, 0, 0, 0, 1, 1);
 
 	switch (nr_components) {
 	case 4:
@@ -266,16 +265,17 @@ init_per_instance_arrays_immd(struct nv50_context *nv50,
 	struct nouveau_bo *bo;
 	unsigned i, b, count = 0;
 
-	for (i = 0; i < nv50->vtxelt_nr; ++i) {
-		if (!nv50->vtxelt[i].instance_divisor)
+	for (i = 0; i < nv50->vtxelt->num_elements; ++i) {
+		if (!nv50->vtxelt->pipe[i].instance_divisor)
 			continue;
 		++count;
-		b = nv50->vtxelt[i].vertex_buffer_index;
+		b = nv50->vtxelt->pipe[i].vertex_buffer_index;
 
-		pos[i] = nv50->vtxelt[i].src_offset +
+		pos[i] = nv50->vtxelt->pipe[i].src_offset +
 			nv50->vtxbuf[b].buffer_offset +
 			startInstance * nv50->vtxbuf[b].stride;
-		step[i] = startInstance % nv50->vtxelt[i].instance_divisor;
+		step[i] = startInstance %
+			nv50->vtxelt->pipe[i].instance_divisor;
 
 		bo = nouveau_bo(nv50->vtxbuf[b].buffer);
 		if (!bo->map)
@@ -296,22 +296,22 @@ init_per_instance_arrays(struct nv50_context *nv50,
 	struct nouveau_channel *chan = tesla->channel;
 	struct nouveau_bo *bo;
 	struct nouveau_stateobj *so;
-	unsigned i, b, count = 0;
+	unsigned i, b, count = 0, num_elements = nv50->vtxelt->num_elements;
 	const uint32_t rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
 
 	if (nv50->vbo_fifo)
 		return init_per_instance_arrays_immd(nv50, startInstance,
 						     pos, step);
 
-	so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 2, nv50->vtxelt_nr * 2);
+	so = so_new(num_elements, num_elements * 2, num_elements * 2);
 
-	for (i = 0; i < nv50->vtxelt_nr; ++i) {
-		if (!nv50->vtxelt[i].instance_divisor)
+	for (i = 0; i < nv50->vtxelt->num_elements; ++i) {
+		if (!nv50->vtxelt->pipe[i].instance_divisor)
 			continue;
 		++count;
-		b = nv50->vtxelt[i].vertex_buffer_index;
+		b = nv50->vtxelt->pipe[i].vertex_buffer_index;
 
-		pos[i] = nv50->vtxelt[i].src_offset +
+		pos[i] = nv50->vtxelt->pipe[i].src_offset +
 			nv50->vtxbuf[b].buffer_offset +
 			startInstance * nv50->vtxbuf[b].stride;
 
@@ -319,7 +319,8 @@ init_per_instance_arrays(struct nv50_context *nv50,
 			step[i] = 0;
 			continue;
 		}
-		step[i] = startInstance % nv50->vtxelt[i].instance_divisor;
+		step[i] = startInstance %
+			nv50->vtxelt->pipe[i].instance_divisor;
 
 		bo = nouveau_bo(nv50->vtxbuf[b].buffer);
 
@@ -344,12 +345,12 @@ step_per_instance_arrays_immd(struct nv50_context *nv50,
 	struct nouveau_bo *bo;
 	unsigned i, b;
 
-	for (i = 0; i < nv50->vtxelt_nr; ++i) {
-		if (!nv50->vtxelt[i].instance_divisor)
+	for (i = 0; i < nv50->vtxelt->num_elements; ++i) {
+		if (!nv50->vtxelt->pipe[i].instance_divisor)
 			continue;
-		if (++step[i] != nv50->vtxelt[i].instance_divisor)
+		if (++step[i] != nv50->vtxelt->pipe[i].instance_divisor)
 			continue;
-		b = nv50->vtxelt[i].vertex_buffer_index;
+		b = nv50->vtxelt->pipe[i].vertex_buffer_index;
 		bo = nouveau_bo(nv50->vtxbuf[b].buffer);
 
 		step[i] = 0;
@@ -367,7 +368,7 @@ step_per_instance_arrays(struct nv50_context *nv50,
 	struct nouveau_channel *chan = tesla->channel;
 	struct nouveau_bo *bo;
 	struct nouveau_stateobj *so;
-	unsigned i, b;
+	unsigned i, b, num_elements = nv50->vtxelt->num_elements;
 	const uint32_t rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
 
 	if (nv50->vbo_fifo) {
@@ -375,14 +376,14 @@ step_per_instance_arrays(struct nv50_context *nv50,
 		return;
 	}
 
-	so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 2, nv50->vtxelt_nr * 2);
+	so = so_new(num_elements, num_elements * 2, num_elements * 2);
 
-	for (i = 0; i < nv50->vtxelt_nr; ++i) {
-		if (!nv50->vtxelt[i].instance_divisor)
+	for (i = 0; i < nv50->vtxelt->num_elements; ++i) {
+		if (!nv50->vtxelt->pipe[i].instance_divisor)
 			continue;
-		b = nv50->vtxelt[i].vertex_buffer_index;
+		b = nv50->vtxelt->pipe[i].vertex_buffer_index;
 
-		if (++step[i] == nv50->vtxelt[i].instance_divisor) {
+		if (++step[i] == nv50->vtxelt->pipe[i].instance_divisor) {
 			step[i] = 0;
 			pos[i] += nv50->vtxbuf[b].stride;
 		}
@@ -740,7 +741,8 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
 			    0, 0, 1, 1);
 	so = *pso;
 	if (!so)
-		*pso = so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 4, 0);
+		*pso = so = so_new(nv50->vtxelt->num_elements,
+				   nv50->vtxelt->num_elements * 4, 0);
 
 	switch (nr_components) {
 	case 4:
@@ -779,6 +781,18 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
 }
 
 void
+nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso)
+{
+	unsigned i;
+
+	for (i = 0; i < cso->num_elements; ++i) {
+		struct pipe_vertex_element *ve = &cso->pipe[i];
+
+		cso->hw[i] = nv50_vbo_vtxelt_to_hw(ve);
+	}
+}
+
+void
 nv50_vbo_validate(struct nv50_context *nv50)
 {
 	struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -798,19 +812,19 @@ nv50_vbo_validate(struct nv50_context *nv50)
 	if (NV50_USING_LOATHED_EDGEFLAG(nv50))
 		nv50->vbo_fifo = 0xffff; /* vertprog can't set edgeflag */
 
-	n_ve = MAX2(nv50->vtxelt_nr, nv50->state.vtxelt_nr);
+	n_ve = MAX2(nv50->vtxelt->num_elements, nv50->state.vtxelt_nr);
 
 	vtxattr = NULL;
-	vtxbuf = so_new(n_ve * 2, n_ve * 5, nv50->vtxelt_nr * 4);
+	vtxbuf = so_new(n_ve * 2, n_ve * 5, nv50->vtxelt->num_elements * 4);
 	vtxfmt = so_new(1, n_ve, 0);
 	so_method(vtxfmt, tesla, NV50TCL_VERTEX_ARRAY_ATTRIB(0), n_ve);
 
-	for (i = 0; i < nv50->vtxelt_nr; i++) {
-		struct pipe_vertex_element *ve = &nv50->vtxelt[i];
+	for (i = 0; i < nv50->vtxelt->num_elements; i++) {
+		struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
 		struct pipe_vertex_buffer *vb =
 			&nv50->vtxbuf[ve->vertex_buffer_index];
 		struct nouveau_bo *bo = nouveau_bo(vb->buffer);
-		uint32_t hw = nv50_vbo_vtxelt_to_hw(ve);
+		uint32_t hw = nv50->vtxelt->hw[i];
 
 		if (!vb->stride &&
 		    nv50_vbo_static_attrib(nv50, i, &vtxattr, ve, vb)) {
@@ -859,7 +873,7 @@ nv50_vbo_validate(struct nv50_context *nv50)
 		so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 1);
 		so_data  (vtxbuf, 0);
 	}
-	nv50->state.vtxelt_nr = nv50->vtxelt_nr;
+	nv50->state.vtxelt_nr = nv50->vtxelt->num_elements;
 
 	so_ref (vtxfmt, &nv50->state.vtxfmt);
 	so_ref (vtxbuf, &nv50->state.vtxbuf);
@@ -1020,13 +1034,13 @@ emit_prepare(struct nv50_context *nv50, struct nv50_vbo_emitctx *emit,
 	emit->nr_ve = 0;
 	emit->vtx_dwords = 0;
 
-	for (i = 0; i < nv50->vtxelt_nr; ++i) {
+	for (i = 0; i < nv50->vtxelt->num_elements; ++i) {
 		struct pipe_vertex_element *ve;
 		struct pipe_vertex_buffer *vb;
 		unsigned n, size, nr_components;
 		const struct util_format_description *desc;
 
-		ve = &nv50->vtxelt[i];
+		ve = &nv50->vtxelt->pipe[i];
 		vb = &nv50->vtxbuf[ve->vertex_buffer_index];
 		if (!(nv50->vbo_fifo & (1 << i)) || ve->instance_divisor)
 			continue;



More information about the mesa-commit mailing list