diff options
-rw-r--r-- | src/gallium/drivers/nvfx/nv30_fragtex.c | 33 | ||||
-rw-r--r-- | src/gallium/drivers/nvfx/nv40_fragtex.c | 41 | ||||
-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, 83 insertions, 72 deletions
diff --git a/src/gallium/drivers/nvfx/nv30_fragtex.c b/src/gallium/drivers/nvfx/nv30_fragtex.c index e0356783ea0..dec073ac900 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 bffdf0893c3..0068b1ba54a 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); - - return so; + 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); + + 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 2022f6e5121..7f6e5500e54 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 84e4eb10042..e239235c3f5 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 cb6ae89e2ab..8adf59d8e3d 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); |