nvfx: so->RING_3D: fragtex
authorLuca Barbieri <luca@luca-barbieri.com>
Sun, 14 Mar 2010 19:50:03 +0000 (20:50 +0100)
committerLuca Barbieri <luca@luca-barbieri.com>
Mon, 12 Apr 2010 10:13:16 +0000 (12:13 +0200)
src/gallium/drivers/nvfx/nv30_fragtex.c
src/gallium/drivers/nvfx/nv40_fragtex.c
src/gallium/drivers/nvfx/nvfx_context.h
src/gallium/drivers/nvfx/nvfx_fragtex.c
src/gallium/drivers/nvfx/nvfx_state_emit.c

index e0356783ea061a9329fe860f61944c3d2e3237ce..dec073ac9003622bee6f6a627cd021f0fb0bf447 100644 (file)
@@ -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);
 }
index bffdf0893c3cda08af990f7e0e92c0f5813cab5c..0068b1ba54ac044884bb9416ddca619051c9a960 100644 (file)
@@ -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);
 }
index 2022f6e5121861f5ad904eb93a1540b764a12bae..7f6e5500e54a4b7e88c531f1ef17822e140de236 100644 (file)
@@ -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);
index 84e4eb1004299d8caea84e7e68919fc8ab9e1d55..e239235c3f5eb9a4d21b7e3c70d20ef6463beaf4 100644 (file)
@@ -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 = {
index cb6ae89e2ab4e3bb047572de0ef7aa59d0dcb1d6..8adf59d8e3da25bf68f7ff8a76c1124a63f476a8 100644 (file)
@@ -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);