diff options
| -rw-r--r-- | src/gallium/drivers/nvfx/nv30_fragtex.c | 33 | ||||
| -rw-r--r-- | src/gallium/drivers/nvfx/nv40_fragtex.c | 39 | ||||
| -rw-r--r-- | src/gallium/drivers/nvfx/nvfx_context.h | 14 | ||||
| -rw-r--r-- | src/gallium/drivers/nvfx/nvfx_fragtex.c | 57 | ||||
| -rw-r--r-- | src/gallium/drivers/nvfx/nvfx_state_emit.c | 10 | 
5 files changed, 82 insertions, 71 deletions
| diff --git a/src/gallium/drivers/nvfx/nv30_fragtex.c b/src/gallium/drivers/nvfx/nv30_fragtex.c index e0356783ea..dec073ac90 100644 --- a/src/gallium/drivers/nvfx/nv30_fragtex.c +++ b/src/gallium/drivers/nvfx/nv30_fragtex.c @@ -88,21 +88,21 @@ nv30_fragtex_format(uint pipe_format)  } -struct nouveau_stateobj * -nv30_fragtex_build(struct nvfx_context *nvfx, int unit) +void +nv30_fragtex_set(struct nvfx_context *nvfx, int unit)  {  	struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];  	struct nvfx_miptree *nv30mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;  	struct pipe_resource *pt = &nv30mt->base.base;  	struct nouveau_bo *bo = nv30mt->base.bo;  	struct nv30_texture_format *tf; -	struct nouveau_stateobj *so; +	struct nouveau_channel* chan = nvfx->screen->base.channel;  	uint32_t txf, txs;  	unsigned tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;  	tf = nv30_fragtex_format(pt->format);  	if (!tf) -		return NULL; +		return;  	txf  = tf->format;  	txf |= ((pt->last_level>0) ? NV34TCL_TX_FORMAT_MIPMAP : 0); @@ -126,23 +126,24 @@ nv30_fragtex_build(struct nvfx_context *nvfx, int unit)  		break;  	default:  		NOUVEAU_ERR("Unknown target %d\n", pt->target); -		return NULL; +		return;  	}  	txs = tf->swizzle; -	so = so_new(1, 8, 2); -	so_method(so, nvfx->screen->eng3d, NV34TCL_TX_OFFSET(unit), 8); -	so_reloc (so, bo, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0); -	so_reloc (so, bo, txf, tex_flags | NOUVEAU_BO_OR, +	MARK_RING(chan, 9, 2); +	OUT_RING(chan, RING_3D(NV34TCL_TX_OFFSET(unit), 8)); +	OUT_RELOC(chan, bo, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0); +	OUT_RELOC(chan, bo, txf, tex_flags | NOUVEAU_BO_OR,  		      NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1); -	so_data  (so, ps->wrap); -	so_data  (so, NV34TCL_TX_ENABLE_ENABLE | ps->en); -	so_data  (so, txs); -	so_data  (so, ps->filt | 0x2000 /*voodoo*/); -	so_data  (so, (pt->width0 << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | +	OUT_RING(chan, ps->wrap); +	OUT_RING(chan, NV34TCL_TX_ENABLE_ENABLE | ps->en); +	OUT_RING(chan, txs); +	OUT_RING(chan, ps->filt | 0x2000 /*voodoo*/); +	OUT_RING(chan, (pt->width0 << NV34TCL_TX_NPOT_SIZE_W_SHIFT) |  		       pt->height0); -	so_data  (so, ps->bcol); +	OUT_RING(chan, ps->bcol); -	return so; +	nvfx->hw_txf[unit] = txf; +	nvfx->hw_samplers |= (1 << unit);  } diff --git a/src/gallium/drivers/nvfx/nv40_fragtex.c b/src/gallium/drivers/nvfx/nv40_fragtex.c index bffdf0893c..0068b1ba54 100644 --- a/src/gallium/drivers/nvfx/nv40_fragtex.c +++ b/src/gallium/drivers/nvfx/nv40_fragtex.c @@ -106,15 +106,16 @@ nv40_fragtex_format(uint pipe_format)  } -struct nouveau_stateobj * -nv40_fragtex_build(struct nvfx_context *nvfx, int unit) +void +nv40_fragtex_set(struct nvfx_context *nvfx, int unit)  { +	struct nouveau_channel* chan = nvfx->screen->base.channel;  	struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];  	struct nvfx_miptree *nv40mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;  	struct nouveau_bo *bo = nv40mt->base.bo;  	struct pipe_resource *pt = &nv40mt->base.base;  	struct nv40_texture_format *tf; -	struct nouveau_stateobj *so; +  	uint32_t txf, txs, txp;  	unsigned tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; @@ -144,7 +145,7 @@ nv40_fragtex_build(struct nvfx_context *nvfx, int unit)  		break;  	default:  		NOUVEAU_ERR("Unknown target %d\n", pt->target); -		return NULL; +		return;  	}  	if (!(pt->flags & NVFX_RESOURCE_FLAG_LINEAR)) { @@ -156,20 +157,20 @@ nv40_fragtex_build(struct nvfx_context *nvfx, int unit)  	txs = tf->swizzle; -	so = so_new(2, 9, 2); -	so_method(so, nvfx->screen->eng3d, NV34TCL_TX_OFFSET(unit), 8); -	so_reloc (so, bo, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0); -	so_reloc (so, bo, txf, tex_flags | NOUVEAU_BO_OR, -		      NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1); -	so_data  (so, ps->wrap); -	so_data  (so, NV40TCL_TEX_ENABLE_ENABLE | ps->en); -	so_data  (so, txs); -	so_data  (so, ps->filt | tf->sign | 0x2000 /*voodoo*/); -	so_data  (so, (pt->width0 << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | -		       pt->height0); -	so_data  (so, ps->bcol); -	so_method(so, nvfx->screen->eng3d, NV40TCL_TEX_SIZE1(unit), 1); -	so_data  (so, (pt->depth0 << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp); +	MARK_RING(chan, 11 + 2 * !unit, 2); +	OUT_RING(chan, RING_3D(NV34TCL_TX_OFFSET(unit), 8)); +	OUT_RELOC(chan, bo, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0); +	OUT_RELOC(chan, bo, txf, tex_flags | NOUVEAU_BO_OR, +			NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1); +	OUT_RING(chan, ps->wrap); +	OUT_RING(chan, NV40TCL_TEX_ENABLE_ENABLE | ps->en); +	OUT_RING(chan, txs); +	OUT_RING(chan, ps->filt | tf->sign | 0x2000 /*voodoo*/); +	OUT_RING(chan, (pt->width0 << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | pt->height0); +	OUT_RING(chan, ps->bcol); +	OUT_RING(chan, RING_3D(NV40TCL_TEX_SIZE1(unit), 1)); +	OUT_RING(chan, (pt->depth0 << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp); -	return so; +	nvfx->hw_txf[unit] = txf; +	nvfx->hw_samplers |= (1 << unit);  } diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h index 2022f6e512..7f6e5500e5 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.h +++ b/src/gallium/drivers/nvfx/nvfx_context.h @@ -167,6 +167,8 @@ struct nvfx_context {  	unsigned vbo_bo;  	unsigned hw_vtxelt_nr; +	uint8_t hw_samplers; +	uint32_t hw_txf[8];  };  static INLINE struct nvfx_context * @@ -220,23 +222,23 @@ extern void nvfx_draw_elements_swtnl(struct pipe_context *pipe,  extern void nvfx_fragprog_destroy(struct nvfx_context *,  				    struct nvfx_fragment_program *); +/* nvfx_fragtex.c */ +extern void +nvfx_fragtex_relocate(struct nvfx_context *nvfx); +  /* nv30_fragtex.c */  extern void  nv30_sampler_state_init(struct pipe_context *pipe,  			  struct nvfx_sampler_state *ps,  			  const struct pipe_sampler_state *cso); -extern void nv30_fragtex_bind(struct nvfx_context *); -extern struct nouveau_stateobj * -nv30_fragtex_build(struct nvfx_context *nvfx, int unit); +extern void nv30_fragtex_set(struct nvfx_context *nvfx, int unit);  /* nv40_fragtex.c */  extern void  nv40_sampler_state_init(struct pipe_context *pipe,  			  struct nvfx_sampler_state *ps,  			  const struct pipe_sampler_state *cso); -extern void nv40_fragtex_bind(struct nvfx_context *); -extern struct nouveau_stateobj * -nv40_fragtex_build(struct nvfx_context *nvfx, int unit); +extern void nv40_fragtex_set(struct nvfx_context *nvfx, int unit);  /* nvfx_state.c */  extern void nvfx_init_state_functions(struct nvfx_context *nvfx); diff --git a/src/gallium/drivers/nvfx/nvfx_fragtex.c b/src/gallium/drivers/nvfx/nvfx_fragtex.c index 84e4eb1004..e239235c3f 100644 --- a/src/gallium/drivers/nvfx/nvfx_fragtex.c +++ b/src/gallium/drivers/nvfx/nvfx_fragtex.c @@ -1,43 +1,58 @@  #include "nvfx_context.h" +#include "nvfx_resource.h"  static boolean  nvfx_fragtex_validate(struct nvfx_context *nvfx)  { -	struct nvfx_fragment_program *fp = nvfx->fragprog; -	struct nvfx_state *state = &nvfx->state; -	struct nouveau_stateobj *so; +	struct nouveau_channel* chan = nvfx->screen->base.channel;  	unsigned samplers, unit; -	samplers = state->fp_samplers & ~fp->samplers; +	samplers = nvfx->dirty_samplers; +	if(!samplers) +		return FALSE; +  	while (samplers) {  		unit = ffs(samplers) - 1;  		samplers &= ~(1 << unit); -		so = so_new(1, 1, 0); -		so_method(so, nvfx->screen->eng3d, NV34TCL_TX_ENABLE(unit), 1); -		so_data  (so, 0); -		so_ref(so, &nvfx->state.hw[NVFX_STATE_FRAGTEX0 + unit]); -		so_ref(NULL, &so); -		state->dirty |= (1ULL << (NVFX_STATE_FRAGTEX0 + unit)); +		if(nvfx->fragment_sampler_views[unit] && nvfx->tex_sampler[unit]) { +			if(!nvfx->is_nv4x) +				nv30_fragtex_set(nvfx, unit); +			else +				nv40_fragtex_set(nvfx, unit); +		} else { +			WAIT_RING(chan, 2); +			/* this is OK for nv40 too */ +			OUT_RING(chan, RING_3D(NV34TCL_TX_ENABLE(unit), 1)); +			OUT_RING(chan, 0); +			nvfx->hw_samplers &= ~(1 << unit); +		}  	} +	nvfx->dirty_samplers = 0; +	return FALSE; +} + +void +nvfx_fragtex_relocate(struct nvfx_context *nvfx) +{ +	struct nouveau_channel* chan = nvfx->screen->base.channel; +	unsigned samplers, unit; +	unsigned tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; -	samplers = nvfx->dirty_samplers & fp->samplers; +	samplers = nvfx->hw_samplers;  	while (samplers) {  		unit = ffs(samplers) - 1;  		samplers &= ~(1 << unit); -		if(!nvfx->is_nv4x) -			so = nv30_fragtex_build(nvfx, unit); -		else -			so = nv40_fragtex_build(nvfx, unit); +		struct nvfx_miptree* mt = (struct nvfx_miptree*)nvfx->fragment_sampler_views[unit]->texture; +		struct nouveau_bo *bo = mt->base.bo; -		so_ref(so, &nvfx->state.hw[NVFX_STATE_FRAGTEX0 + unit]); -		so_ref(NULL, &so); -		state->dirty |= (1ULL << (NVFX_STATE_FRAGTEX0 + unit)); +		MARK_RING(chan, 3, 3); +		OUT_RELOC(chan, bo, RING_3D(NV34TCL_TX_OFFSET(unit), 2), tex_flags | NOUVEAU_BO_DUMMY, 0, 0); +		OUT_RELOC(chan, bo, 0, tex_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_DUMMY, 0, 0); +		OUT_RELOC(chan, bo, nvfx->hw_txf[unit], tex_flags | NOUVEAU_BO_OR | NOUVEAU_BO_DUMMY, +				NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1);  	} - -	nvfx->state.fp_samplers = fp->samplers; -	return FALSE;  }  struct nvfx_state_entry nvfx_state_fragtex = { diff --git a/src/gallium/drivers/nvfx/nvfx_state_emit.c b/src/gallium/drivers/nvfx/nvfx_state_emit.c index cb6ae89e2a..8adf59d8e3 100644 --- a/src/gallium/drivers/nvfx/nvfx_state_emit.c +++ b/src/gallium/drivers/nvfx/nvfx_state_emit.c @@ -100,16 +100,8 @@ nvfx_state_relocate(struct nvfx_context *nvfx)  {  	struct nouveau_channel *chan = nvfx->screen->base.channel;  	struct nvfx_state *state = &nvfx->state; -	unsigned i, samplers; -  	so_emit_reloc_markers(chan, state->hw[NVFX_STATE_FB]); -	for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { -		if (!(samplers & (1 << i))) -			continue; -		so_emit_reloc_markers(chan, -				      state->hw[NVFX_STATE_FRAGTEX0+i]); -		samplers &= ~(1ULL << i); -	} +	nvfx_fragtex_relocate(nvfx);  	so_emit_reloc_markers(chan, state->hw[NVFX_STATE_FRAGPROG]);  	if (nvfx->render_mode == HW)  		nvfx_vbo_relocate(nvfx); | 
