diff options
Diffstat (limited to 'src/gallium')
| -rw-r--r-- | src/gallium/drivers/nv50/nv50_program.c | 19 | ||||
| -rw-r--r-- | src/gallium/drivers/nv50/nv50_program.h | 1 | ||||
| -rw-r--r-- | src/gallium/drivers/nv50/nv50_screen.c | 3 | ||||
| -rw-r--r-- | src/gallium/drivers/nv50/nv50_vbo.c | 45 | 
4 files changed, 64 insertions, 4 deletions
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 679c28ce4b..ce3fa5fc88 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -159,6 +159,8 @@ struct nv50_pc {  	unsigned insn_nr;  	boolean allow32; + +	uint8_t edgeflag_out;  };  static INLINE struct nv50_reg * @@ -2554,10 +2556,16 @@ prep_inspect_insn(struct nv50_pc *pc, const struct tgsi_full_instruction *insn)  	mask = dst->WriteMask;          if (dst->File == TGSI_FILE_TEMPORARY) -                reg = pc->temp; +		reg = pc->temp;          else -        if (dst->File == TGSI_FILE_OUTPUT) -                reg = pc->result; +	if (dst->File == TGSI_FILE_OUTPUT) { +		reg = pc->result; + +		if (insn->Instruction.Opcode == TGSI_OPCODE_MOV && +		    dst->Index == pc->edgeflag_out && +		    insn->Src[0].Register.File == TGSI_FILE_INPUT) +			pc->p->cfg.edgeflag_in = insn->Src[0].Register.Index; +	}  	if (reg) {  		for (c = 0; c < 4; c++) { @@ -2856,6 +2864,9 @@ nv50_program_tx_prep(struct nv50_pc *pc)  					if (p->cfg.io_nr > first)  						p->cfg.io_nr = first;  					break; +				case TGSI_SEMANTIC_EDGEFLAG: +					pc->edgeflag_out = first; +					break;  					/*  				case TGSI_SEMANTIC_CLIP_DISTANCE:  					p->cfg.clpd = MIN2(p->cfg.clpd, first); @@ -3104,6 +3115,8 @@ ctor_nv50_pc(struct nv50_pc *pc, struct nv50_program *p)  	p->cfg.two_side[0].hw = 0x40;  	p->cfg.two_side[1].hw = 0x40; +	p->cfg.edgeflag_in = pc->edgeflag_out = 0xff; +  	switch (p->type) {  	case PIPE_SHADER_VERTEX:  		p->cfg.psiz = 0x40; diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h index 4a90c372ce..461fec1d89 100644 --- a/src/gallium/drivers/nv50/nv50_program.h +++ b/src/gallium/drivers/nv50/nv50_program.h @@ -58,6 +58,7 @@ struct nv50_program {  		/* VP only */  		uint8_t clpd, clpd_nr;  		uint8_t psiz; +		uint8_t edgeflag_in;  	} cfg;  }; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index d443ca3ad0..2435f65ed2 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -441,6 +441,9 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)  	so_method(so, screen->tesla, NV50TCL_SCISSOR_ENABLE, 1);  	so_data  (so, 1); +	so_method(so, screen->tesla, 0x15e4, 1); +	so_data  (so, 1); /* default edgeflag to TRUE */ +  	so_emit(chan, so);  	so_ref (so, &screen->static_init);  	so_ref (NULL, &so); diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index f7fa0659e8..39324e30f6 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -372,6 +372,10 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,  		so_data  (so, fui(v[1]));  		break;  	case 1: +		if (attrib == nv50->vertprog->cfg.edgeflag_in) { +			so_method(so, tesla, 0x15e4, 1); +			so_data  (so, v[0] ? 1 : 0); +		}  		so_method(so, tesla, NV50TCL_VTX_ATTR_1F(attrib), 1);  		so_data  (so, fui(v[0]));  		break; @@ -401,6 +405,9 @@ nv50_vbo_validate(struct nv50_context *nv50)  		    !(nv50->vtxbuf[i].buffer->usage & PIPE_BUFFER_USAGE_VERTEX))  			nv50->vbo_fifo = 0xffff; +	if (nv50->vertprog->cfg.edgeflag_in < 16) +		nv50->vbo_fifo = 0xffff; /* vertprog can't set edgeflag */ +  	n_ve = MAX2(nv50->vtxelt_nr, nv50->state.vtxelt_nr);  	vtxattr = NULL; @@ -479,6 +486,9 @@ struct nv50_vbo_emitctx  	unsigned nr_ve;  	unsigned vtx_dwords;  	unsigned vtx_max; + +	float edgeflag; +	unsigned ve_edgeflag;  };  static INLINE void @@ -622,6 +632,9 @@ emit_prepare(struct nv50_context *nv50, struct nv50_vbo_emitctx *emit,  	if (nv50_map_vbufs(nv50) == FALSE)  		return FALSE; +	emit->ve_edgeflag = nv50->vertprog->cfg.edgeflag_in; + +	emit->edgeflag = 0.5f;  	emit->nr_ve = 0;  	emit->vtx_dwords = 0; @@ -644,7 +657,8 @@ emit_prepare(struct nv50_context *nv50, struct nv50_vbo_emitctx *emit,  		desc = util_format_description(ve->src_format);  		assert(desc); -		size = util_format_get_component_bits(ve->src_format, UTIL_FORMAT_COLORSPACE_RGB, 0); +		size = util_format_get_component_bits( +			ve->src_format, UTIL_FORMAT_COLORSPACE_RGB, 0);  		assert(ve->nr_components > 0 && ve->nr_components <= 4); @@ -686,10 +700,31 @@ emit_prepare(struct nv50_context *nv50, struct nv50_vbo_emitctx *emit,  	}  	emit->vtx_max = 512 / emit->vtx_dwords; +	if (emit->ve_edgeflag < 16) +		emit->vtx_max = 1;  	return TRUE;  } +static INLINE void +set_edgeflag(struct nouveau_channel *chan, +	     struct nouveau_grobj *tesla, +	     struct nv50_vbo_emitctx *emit, uint32_t index) +{ +	unsigned i = emit->ve_edgeflag; + +	if (i < 16) { +		float f = *((float *)(emit->map[i] + index * emit->stride[i])); + +		if (emit->edgeflag != f) { +			emit->edgeflag = f; + +			BEGIN_RING(chan, tesla, 0x15e4, 1); +			OUT_RING  (chan, f ? 1 : 0); +		} +	} +} +  static boolean  nv50_push_arrays(struct nv50_context *nv50, unsigned start, unsigned count)  { @@ -704,6 +739,8 @@ nv50_push_arrays(struct nv50_context *nv50, unsigned start, unsigned count)  		unsigned i, dw, nr = MIN2(count, emit.vtx_max);  	        dw = nr * emit.vtx_dwords; +		set_edgeflag(chan, tesla, &emit, 0); /* nr will be 1 */ +  		BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw);  		for (i = 0; i < nr; ++i)  			emit_vtx_next(chan, &emit); @@ -729,6 +766,8 @@ nv50_push_elements_u32(struct nv50_context *nv50, uint32_t *map, unsigned count)  		unsigned i, dw, nr = MIN2(count, emit.vtx_max);  	        dw = nr * emit.vtx_dwords; +		set_edgeflag(chan, tesla, &emit, *map); +  		BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw);  		for (i = 0; i < nr; ++i)  			emit_vtx(chan, &emit, *map++); @@ -754,6 +793,8 @@ nv50_push_elements_u16(struct nv50_context *nv50, uint16_t *map, unsigned count)  		unsigned i, dw, nr = MIN2(count, emit.vtx_max);  	        dw = nr * emit.vtx_dwords; +		set_edgeflag(chan, tesla, &emit, *map); +  		BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw);  		for (i = 0; i < nr; ++i)  			emit_vtx(chan, &emit, *map++); @@ -779,6 +820,8 @@ nv50_push_elements_u08(struct nv50_context *nv50, uint8_t *map, unsigned count)  		unsigned i, dw, nr = MIN2(count, emit.vtx_max);  	        dw = nr * emit.vtx_dwords; +		set_edgeflag(chan, tesla, &emit, *map); +  		BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw);  		for (i = 0; i < nr; ++i)  			emit_vtx(chan, &emit, *map++);  | 
