summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/nvfx/nv30_fragtex.c33
-rw-r--r--src/gallium/drivers/nvfx/nv40_fragtex.c41
-rw-r--r--src/gallium/drivers/nvfx/nvfx_context.h14
-rw-r--r--src/gallium/drivers/nvfx/nvfx_fragtex.c57
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_emit.c10
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);