diff options
| author | Ben Skeggs <skeggsb@gmail.com> | 2007-12-26 00:37:21 +1100 | 
|---|---|---|
| committer | Ben Skeggs <skeggsb@gmail.com> | 2007-12-26 00:37:21 +1100 | 
| commit | e32e0e2b8ea81e7b49c1cca4a99ac9b43790ce44 (patch) | |
| tree | c20a46610a8754e7a6fe6aa34f0878a57f2c5d24 | |
| parent | d732728590e93de54dd4f4576b394ca2442c3db8 (diff) | |
nv40: use index buffers rather than inline indices.
We probably want to use inline indices in some situations still, but this
commit's primary purpose is to workaround some mis-rendering caused by a
more complicated problem that'll get fixed eventually.
| -rw-r--r-- | src/mesa/pipe/nv40/nv40_vbo.c | 113 | 
1 files changed, 93 insertions, 20 deletions
| diff --git a/src/mesa/pipe/nv40/nv40_vbo.c b/src/mesa/pipe/nv40/nv40_vbo.c index fda32cdb49..7562781fcf 100644 --- a/src/mesa/pipe/nv40/nv40_vbo.c +++ b/src/mesa/pipe/nv40/nv40_vbo.c @@ -149,7 +149,8 @@ nv40_vbo_arrays_update(struct nv40_context *nv40)  }  static boolean -nv40_vbo_validate_state(struct nv40_context *nv40) +nv40_vbo_validate_state(struct nv40_context *nv40, +			struct pipe_buffer_handle *ib, unsigned ib_format)  {  	unsigned inputs; @@ -173,6 +174,14 @@ nv40_vbo_validate_state(struct nv40_context *nv40)  			   NV40TCL_VTXBUF_ADDRESS_DMA1);  	} +	if (ib) { +		BEGIN_RING(curie, 0x181c, 2); +		OUT_RELOCl(ib, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | +			   NOUVEAU_BO_RD); +		OUT_RELOCd(ib, ib_format, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | +			   NOUVEAU_BO_RD | NOUVEAU_BO_OR, 0, 1); +	} +  	BEGIN_RING(curie, 0x1710, 1);  	OUT_RING  (0); /* vtx cache flush */ @@ -186,7 +195,7 @@ nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,  	struct nv40_context *nv40 = (struct nv40_context *)pipe;  	unsigned nr; -	assert(nv40_vbo_validate_state(nv40)); +	assert(nv40_vbo_validate_state(nv40, NULL, 0));  	BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);  	OUT_RING  (nvgl_primitive(mode)); @@ -286,45 +295,109 @@ nv40_draw_elements_u32(struct nv40_context *nv40, void *ib,  	}  } -boolean -nv40_draw_elements(struct pipe_context *pipe, -		   struct pipe_buffer_handle *indexBuffer, unsigned indexSize, -		   unsigned mode, unsigned start, unsigned count) +static boolean +nv40_draw_elements_inline(struct pipe_context *pipe, +			  struct pipe_buffer_handle *ib, unsigned ib_size, +			  unsigned mode, unsigned start, unsigned count)  {  	struct nv40_context *nv40 = (struct nv40_context *)pipe; -	void *ib; +	struct pipe_winsys *ws = pipe->winsys; +	void *map; -	assert(nv40_vbo_validate_state(nv40)); +	assert(nv40_vbo_validate_state(nv40, NULL, 0)); -	ib = pipe->winsys->buffer_map(pipe->winsys, indexBuffer, -				      PIPE_BUFFER_FLAG_READ); -	if (!ib) { -		NOUVEAU_ERR("Couldn't map index buffer!!\n"); -		return FALSE; -	} +	map = ws->buffer_map(ws, ib, PIPE_BUFFER_FLAG_READ); +	if (!ib) +		assert(0);  	BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);  	OUT_RING  (nvgl_primitive(mode)); -	switch (indexSize) { +	switch (ib_size) {  	case 1: -		nv40_draw_elements_u08(nv40, ib, start, count); +		nv40_draw_elements_u08(nv40, map, start, count);  		break;  	case 2: -		nv40_draw_elements_u16(nv40, ib, start, count); +		nv40_draw_elements_u16(nv40, map, start, count);  		break;  	case 4: -		nv40_draw_elements_u32(nv40, ib, start, count); +		nv40_draw_elements_u32(nv40, map, start, count);  		break;  	default: -		NOUVEAU_ERR("unsupported elt size %d\n", indexSize); +		assert(0); +		break; +	} + +	BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); +	OUT_RING  (0); + +	ws->buffer_unmap(ws, ib); + +	return TRUE; +} + +static boolean +nv40_draw_elements_vbo(struct pipe_context *pipe, +		       struct pipe_buffer_handle *ib, unsigned ib_size, +		       unsigned mode, unsigned start, unsigned count) +{ +	struct nv40_context *nv40 = (struct nv40_context *)pipe; +	unsigned nr; + +	switch (ib_size) { +	case 2: +		assert(nv40_vbo_validate_state(nv40, ib, 0x00000010));  		break; +	case 4: +		assert(nv40_vbo_validate_state(nv40, ib, 0x00000000)); +		break; +	default: +		assert(0); +	} + + +	BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); +	OUT_RING  (nvgl_primitive(mode)); + +	nr = (count & 0xff); +	if (nr) { +		BEGIN_RING(curie, 0x1824, 1); +		OUT_RING  (((nr - 1) << 24) | start); +		start += nr; +	} + +	nr = count >> 8; +	while (nr) { +		unsigned push = nr > 2047 ? 2047 : nr; + +		nr -= push; + +		BEGIN_RING_NI(curie, 0x1824, push); +		while (push--) { +			OUT_RING(((0x100 - 1) << 24) | start); +			start += 0x100; +		}  	}  	BEGIN_RING(curie, NV40TCL_BEGIN_END, 1);  	OUT_RING  (0); -	pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer); +	return TRUE; +} + +boolean +nv40_draw_elements(struct pipe_context *pipe, +		   struct pipe_buffer_handle *indexBuffer, unsigned indexSize, +		   unsigned mode, unsigned start, unsigned count) +{ +	if (indexSize != 1) { +		nv40_draw_elements_vbo(pipe, indexBuffer, indexSize, +				       mode, start, count); +	} else { +		nv40_draw_elements_inline(pipe, indexBuffer, indexSize, +					  mode, start, count); +	} +  	pipe->flush(pipe, 0);  	return TRUE;  } | 
